Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Earn badges and make progress

You're on your way to the next level! Join the Kudos program to earn points and save your progress.

Deleted user Avatar
Deleted user

Level 1: Seed

25 / 150 points

Next: Root


1 badge earned


Participate in fun challenges

Challenges come and go, but your rewards stay with you. Do more to earn more!


Gift kudos to your peers

What goes around comes around! Share the love by gifting kudos to your peers.


Rise up in the ranks

Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!


Scriptrunner Listener: How do you trigger 'Create a sub-task' based on checkbox value?

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.
Sep 25, 2023

Similar to this question, but I'm running into an error where the auto creating subtask will only create the last option in the checkbox list, and not all options selected after an edit.


Checkbox field at the parent issue after 1 edit:

  • Option 1 - checked
  • Option 2
  • Option 3 - checked

Expected Results, subtask's summary as:

  • Subtask: Option 1
  • Subtask: Option 3

Actual Results:

  • Subtask: Option 3

In the listener script, I set Event trigger to Issue Created and Issue Updated. Under Conditions I use:

import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.issue.customfields.option.Option

def cf = customFieldManager.getCustomFieldObjectsByName("Checkbox")

def cfValue = cf.getAt(0).getValue(issue)

def subtaskSummaries = (cf as Collection<Option>)*.value

if( == "Parent" && cfValue != null){


        return true


Target Issue Type = Subtask
Subtask summary left blank, no fields copied.
Under Additional issue actions I use:
def cf = customFieldManager.getCustomFieldObjectsByName("Checkbox").getAt(0)

def cfValue = sourceIssue.getCustomFieldValue(cf)

def subtaskSummaries = (cf as Collection<Option>)*.value

subtaskSummaries.each {


        issue.summary = "Subtask: " + it


Any suggestions why the script skips Subtask: Option 1?  

2 answers

1 accepted

1 vote
Answer accepted

Here is a scripted listener I wrote that is very similar to what you want.  It uses a checkbox field as the source for creating subtasks.  The subtask summary is a bit over the top, but it's what they wanted :shrug:


package Listeners

import com.atlassian.jira.issue.Issue

import com.atlassian.jira.event.type.EventType

import com.atlassian.jira.event.issue.IssueEvent


final sourceFieldName = "Required Reviews"

IssueEvent issueEvent = event as IssueEvent

Issue parentIssue = issueEvent.issue


if (!issueEvent?.getEventTypeId()?.equals(EventType.ISSUE_CREATED_ID) &&

   !issueEvent?.getChangeLog()?.getRelated("ChildChangeItem")?.find { it.field == sourceFieldName })



import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.issue.MutableIssue

import com.atlassian.jira.issue.customfields.option.Option

import com.atlassian.jira.issue.customfields.manager.OptionsManager

import com.atlassian.jira.user.ApplicationUser

import com.atlassian.jira.event.type.EventDispatchOption


// Logging configuration

import org.apache.log4j.Logger

import org.apache.log4j.Level

final Logger log = Logger.getLogger("com.joby.melville")




// Re-indexing

import com.atlassian.jira.issue.index.IssueIndexingService

import com.atlassian.jira.util.ImportUtils

def reIndexIssue(issue) {

    //Re-index the issue after update

    boolean wasIndexing = ImportUtils.isIndexIssues()






def optionSuffix = " Review: " // tacked on to cf option to create Summary Prefix

def subtaskIssueType = "Review Subtask"

def selectFieldsToClone = [ 'Installation Stage', 'Document Category']

def constantManager = ComponentAccessor.getConstantsManager()

def customFieldManager = ComponentAccessor.getCustomFieldManager()

def issueFactory = ComponentAccessor.getIssueFactory()

def subTaskManager = ComponentAccessor.getSubTaskManager()

def issueManager = ComponentAccessor.getIssueManager()

ApplicationUser user = issueEvent.getUser()


def cf = customFieldManager.getCustomFieldObjects(issue).findByName(sourceFieldName)

if (cf == null)


def optionList = (issue.getCustomFieldValue(cf) as Collection<Option>)*.value

def modified = false

optionList.each {

    subtaskSummary = it + optionSuffix"${sourceFieldName}: ${subtaskSummary}")

    if (!issue.getSubTaskObjects()*.summary.find { it.startsWith(subtaskSummary) }) {

        // no existing subtask has a matching prefix

        MutableIssue newSubTask = issueFactory.getIssue()

        newSubTask.setSummary(subtaskSummary + parentIssue.summary)




        newSubTask.setIssueTypeId(constantManager.getAllIssueTypeObjects().find{it.getName() == subtaskIssueType}.id)

        def cff

        selectFieldsToClone.each {

            cff = customFieldManager.getCustomFieldObjects(parentIssue).findByName(it)

            if (cff == null)

                log.error("Custom Field not found: ${it}")


               newSubTask.setCustomFieldValue(cff, parentIssue.getCustomFieldValue(cff))



        def newIssueParams = ["issue" : newSubTask] as Map<String,Object>

        issueManager.createIssueObject(user, newIssueParams)

        subTaskManager.createSubTaskIssueLink(parentIssue, newSubTask, user)


        modified = true "Created ${newSubTask.summary}"



if (modified)

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.
Sep 26, 2023

@Chris Melville Thank you so much! this works!

I only made a few changes to the re-indexing portion. For some reason I get a "cannot find matching method" on IssueIndexingService, even though I've imported the class. I even trying defining it as variable.

So instead of using 'reIndexIssue' i just tell it to reindex at the very end within the curly brackets:

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService)

boolean wasIndexing = ImportUtils.isIndexIssues()



1 vote
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Sep 25, 2023

You can't use the "create sub task" built-in script to create multiple subtasks.

You'll have to use a "Custom scripted listener" and build the sub-tasks yourself.

You'll have to loop through all the selected options in the checkbox field and create sub-tasks in that loop.

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.
Sep 26, 2023

@Peter-Dave Sheehan that makes more sense. I was wondering why it was only creating only 1 subtask at a time, even when I add logs to track.

Thanks for the response back.

Suggest an answer

Log in or Sign up to answer
AUG Leaders

Atlassian Community Events