Behaviours
Description
The behaviours functionality allows an administrator to create one more or behaviours. A behaviour defines how fields behave for issues in a given project or issue context. Some examples of behaviours are:
-
Making a field mandatory depending on other data entered on the issue screen (i.e during an issue creation or an issue transition)
-
Making a field read-only dependent on user role or group
-
Doing server-side validation of field data, before the issue screen is submitted
-
Setting a field value dependent on other issue screen data
Once you’ve created the behaviour, apply it to a test project so you can test it works as expected. Then apply it to a real project.
Be sure to read through the behavior limitations before using a behavior or if you’re having problems getting your behavior to work.
New to Behaviours? Check out our Behaviours Tutorial. |
Navigating to Behaviours
-
Click the Cog in the top ribbon to open the Administration menu and select Manage Apps.
-
Select Behaviours from the side menu under Behaviours. Here you can view and edit existing behaviours.
-
To add a new behaviour, enter a Name and optionally, a Description under Add Behaviour.
Examples
Setting a default Description
This simple example can be used as a tutorial. Further worked examples can be found in the Recipes section - Behaviours Examples.
To create a new Behaviour. Go to the Administration screen, and click the Behaviours link in the Behaviours section, or press gg
or .
and type Behaviours.

Click on Fields:

Click the Create Initialiser link:

Enter the following in the Script section (leave the first two fields blank):
def desc = getFieldById("description")
def defaultValue = """h2. How to reproduce
* step 1
* step 2
h2. Expected Result
The widget should appear
h2. Actual Result
The widget doesn't appear""".replaceAll(/ /, '')
if (!underlyingIssue?.description) { (1)
desc.setFormValue(defaultValue)
}
1 | don’t overwrite the description if it already exists |
Then click on the Update
button.
Now click the Add One now
link to map this behaviour to a project:

Select one or more projects, then click Add Mapping:

This is a very simple configuration and should be used to check everything is working. For information about Jira Service Desk mappings, see this page.
Create a new issue in the project that you have associated with this behaviour. You should see the default description. (If it doesn’t, see trouble-shooting below).

Using a server-side validator to set the Fix Versions required
A common scenario is that, when you mark an issue as resolved with the resolution of Fixed, you want the developer to specify the Fix Version. However, it doesn’t make sense to require a fix version when the resolution is Won’t Fix.
We solve that by using a server-side validator to mark the fix versions field as required, but only when the resolution is Fixed.
Create a new behaviour, or edit your current sample one. Click Add Field, and add the Resolution field.
Our server-side script, when written, will be called the first time this field appears, and any time the user changes it in the dialog.

Now click Add serverside script as we did previously. The script to enter is:
import com.atlassian.jira.issue.resolution.Resolution
def resolutionField = getFieldById("resolution")
def fixVersionsField = getFieldById("fixVersions")
def resolution = resolutionField.getValue() as Resolution
if (resolution.name == "Fixed") {
fixVersionsField.setRequired(true)
fixVersionsField.setHidden(false)
} else {
fixVersionsField.setRequired(false)
fixVersionsField.setHidden(true)
}
This example sets the fix versions field to required and shown if the resolution is Fixed, and to optional and hidden if the resolution is anything else.
Now, Resolve an issue. Experiment with changing the resolution value. The fix versions field should change accordingly:

A good experiment now would be to modify the script so that instead of hiding the field it’s made read-only. To do, change setHidden
to setReadOnly
.
If you have created a new behaviour do not forget to map it to a project, or project/issue type combination. |
You might want to do something similar whereby if the Duplicate resolution is selected, the Linked Issues field is shown, if there not already a duplicate link for that issue |
Live Editing
Using an inline script can be painful as you have to keep clicking buttons and saving. It’s more productive to point to a file, then you can just modify that. It will be reloaded automatically.

Note that if you have a groovy script as opposed to a class, as in the previous examples, the method name should be run
.
When configured like this you can modify your code without even leaving the Resolve Issue dialog, let alone doing a page refresh.
The path to the script can be relative to a script root. |
Tip for IDE users
If using an IDE you can get code completion by adding the following lines at the beginning of your script:
|
Migration of Behaviours
Currently there is no automated way of migrating behaviours. There are some REST APIs that you can use that will help migrating the configuration, although care must be taken.
The following REST API provides the mapping between behaviours, and projects/issue types.
/rest/scriptrunner/behaviours/latest/config
This will yield something like:
<Behaviours>
<project pid="10001" configuration="1"/>
<project pid="10003">
<issuetype id="10004" configuration="2"/>
<issuetype id="10000" configuration="2"/>
</project>
</Behaviours>
Each configuration ID above is a single behaviour, which you can get with:
/rest/scriptrunner/behaviours/latest/config/2
where 2
is the ID of one of the behaviours above.
This call will give a behaviour configuration like:
<config use-validator-plugin="false" validate-jira-requiredness="false" name="test">
<field id="customfield_10011" readonly="true"/>
<field
id="customfield_10013" validator-method="" validator-class="" validator="server"
validator-script=" getFieldByName("TextFieldB").setFormValue("Hello World") "/>
<field id="customfield_10014" required="true"/>
</config>
As you can see, custom fields are identified by their ID. If you are translating this to another system you will need to check and update any custom field IDs that don’t match. If your dev environment is a copy of your production environment you should be fine.
Likewise, project and issue types are represented by the IDs and might need updating.
Once you have updated the XML, you can post it to your production instance, using eg:
curl -X POST -u admin:admin --header "X-Atlassian-Token:no-check" --header "Content-Type:application/xml" -d @b1.xml <jira-base-url>/rest/scriptrunner/behaviours/latest/config/1
where b1.xml
is the contents of the behaviour configuration, and admin:admin
is an admin username and password.
If a behaviour already exists with this ID the command above will overwrite it. |
Once you have recreated any behaviours, you can write the mappings to the production server:
curl -X POST -u admin:admin --header "X-Atlassian-Token:no-check" --header "Content-Type:application/xml" -d @bh.xml <jira-base-url>/rest/scriptrunner/behaviours/latest/config
where bh.xml
contains the mappings retrieved in Step 1.
This will overwrite any mappings already defined. Make sure you test the procedure on a non-production instance first. |
Please check the documentation for curl for the system you are on. We are not able to support you in this procedure.
|
Limitations
Javascript-based
Behaviours rely on client-side javascript. In most environments users are free to disable javascript in their browser. If security of a field is critical, behaviours alone won’t be enough to protect it from malicious data entry. However, the typical use cases are to prompt the user that they should be entering another field depending on some condition, or to hide a field for clarity’s sake. In these cases, the user is better off with behaviours, and no worse off than they were without them.
If a behaviour makes a field read-only, the issue history can also reveal if that rule has been subverted.
However, one of the intentions of this plugin is to provide a more structured, maintainable way to customize fields than entering javascript in a field description.
Another side effect is that Behaviours can’t override other server-side validation rules, such as field configurations and workflow validators. For example, if you have a field configuration that specifies a field is required, a behaviour can’t really remove that requirement. You can do the opposite, however, and take a non-required field and make it required from the client’s perspective.
Bulk Edit
No support for bulk edits, at the moment. This could be added, however, all issues part of the bulk edit would need to have the same behaviour associated for it to be doable.
Latency
The field behaviours are retrieved from the server after the form has loaded in the browser. In my environment this takes approximately 80 ms so is not noticeable by humans. Over the public internet this may be a lot worse, and so the delay in the styling being applied may be appreciable for the users.
Remote API
Due to limitation 1, i.e. JavaScript based, the behaviours are not enforced when using the remote API.
Multiple behaviours on the same field can lead to confusion
It is possible to apply multiple behaviours in overlapping contexts. For example, you may have a behaviour that is mapped to one project and all issue types, then another behaviour that is mapped to all projects and one particular issue type.
Normally, this is fine. All applicable behaviours are applied in any given context. However, if both behaviours try to manipulate the same field, it’s possible for them to contradict each other. For example, if one behaviour tries to set the field to be read-only, but the other sets the field to be writeable, only one can win. If both behaviours set the field’s value to something specific, only one will be applied.
If a behaviour appears to be working inconsistently, this is a likely cause.
It may be helpful in these circumstances to use one server-side behaviour for that field. You can map it to every applicable context, then provide some detailed logic specifying in one place what ought to happen in which circumstances. See Scripted Conditions for some sample code that you can re-purpose inside a behaviour.
Screens
Behaviours function on the Create Issue, Update/Edit Issue, Assign Issue, and Workflow Transition screens.
On the View Issue screen, trying to edit a field with a behaviour will launch the edit issue screen, instead of the normal inline editor.
Behaviours will not work on the Move Issue screen. They also do not work for any bulk issue operations or any issue edits that bypass the UI such as the REST API and other ScriptRunner scripts.
Getting help
If you have any problems, please include in your bug report:
-
server logs. You can switch these on by using the enable logging link from the Behaviours Admin screen.

To do so permanently, include these lines in your log4j.properties file:
log4j.category.com.onresolve.jira.groovy = DEBUG, console, filelog
log4j.additivity.com.onresolve.jira.groovy = false
-
For the problematic behaviour, click Edit, and include the XML snippet you see there.
-
Description of any custom field types involved, eg their type.
Have questions? Visit the Atlassian Community to connect, share, and learn with other Atlassian users and experts, including Adaptavist staff.
Ask a question about ScriptRunner for JIRA, Bitbucket Server, or Confluence.
Want to learn more? Check out courses on Adaptavist Learn, an online platform to onboard and train new users for Atlassian solutions.