Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Script runner workflow

kelly_jee October 13, 2025

I would like to set a rule so that when Custom Field 1 is set to A, Custom Field 2 cannot be left blank. If it’s blank, an error should appear and the transition to the next status should be blocked.

However, the script I used isn’t working — can anyone help?

I’ve also added a validator that requires Story Points to be filled in before moving to the next status.

 

import com.atlassian.jira.component.ComponentAccessor

def customFieldManager = ComponentAccessor.getCustomFieldManager()

// Get fields by ID — update these IDs to match your actual custom field IDs
def customField1 = customFieldManager.getCustomFieldObject("customfield_10001") // Custom Field 1
def customField2 = customFieldManager.getCustomFieldObject("customfield_10002") // Custom Field 2

// Get field values
def field1Value = issue.getCustomFieldValue(customField1)?.toString()
def field2Value = issue.getCustomFieldValue(customField2)

// Validation logic
if (field1Value?.equalsIgnoreCase("A")) {
if (!field2Value) {
// Show error and block transition
invalidInputException = new com.opensymphony.workflow.InvalidInputException(
"Custom Field 2 must be filled when Custom Field 1 = A."
)
throw invalidInputException
}
}

// Allow transition
return true

1 answer

0 votes
Gor Greyan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 13, 2025

Hi @kelly_jee

Please try the following one.

import com.atlassian.jira.component.ComponentAccessor
import com.opensymphony.workflow.InvalidInputException
import com.atlassian.jira.issue.customfields.option.Option

def cfm = ComponentAccessor.customFieldManager

// Update these IDs to your own customfield IDs
def cf1 = cfm.getCustomFieldObject("customfield_10001") // Custom Field 1
def cf2 = cfm.getCustomFieldObject("customfield_10002") // Custom Field 2

def v1 = issue.getCustomFieldValue(cf1)
def v2 = issue.getCustomFieldValue(cf2)

// Helper: check if empty across common field types
boolean isBlank(def v) {
if (v == null) return true
if (v instanceof String) return v.trim().isEmpty()
if (v instanceof Collection) return v.isEmpty()
// Numbers/users/dates/options: if you have a value object at all, we consider it not blank
return false
}

// Read label "A" correctly for selects or strings
boolean field1IsA = (
(v1 instanceof Option && v1.value?.equalsIgnoreCase("A")) ||
(!(v1 instanceof Option) && v1?.toString()?.equalsIgnoreCase("A"))
)

if (field1IsA && isBlank(v2)) {
// Attach error to Custom Field 2 so it shows inline on the transition screen
throw new InvalidInputException(cf2.id, "Custom Field 2 must be filled when Custom Field 1 = A.")
}

return true

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
PREMIUM
PERMISSIONS LEVEL
Product Admin
TAGS
AUG Leaders

Atlassian Community Events