Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
Deleted user
0 / 0 points
badges earned

Your Points Tracker
  • Global
  • Feed

Badge for your thoughts?

You're enrolled in our new beta rewards program. Join our group to get the inside scoop and share your feedback.

Join group
Give the gift of kudos
You have 0 kudos available to give
Who do you want to recognize?
Why do you want to recognize them?
Great job appreciating your peers!
Check back soon to give more kudos.

Past Kudos Given
No kudos given
You haven't given any kudos yet. Share the love above and you'll see it here.

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

cURL command not working in ScriptRunner post function

We are currently trying to use ScriptRunner to execute a workflow transition on a remote JIRA instance via a post function and are running into some interesting issues.  Basically, we have a custom workflows on two JIRA instances (say A and B).  When we execute a specific workflow transition on an issue in A, we want to also execute a workflow transition on a remotely linked issue in B.

I have attached the script we are using.  It starts off by declaring parameters that are going to be used in the remainder of the script.  It then grabs all remote issue links for the current issue, and for each one of them, calls the executeTransition function.  That function will grab all transitions for the remote issue using the JIRA REST API, find the appropriate transition, and then make a POST call to the JIRA REST API to execute the workflow transition.

Here is the API call  We also use cURL in order to accomplish this (I haven't found a better way of making POST requests using the native groovy language).

Here's the issue we are running into: the script works everywhere EXCEPT in JIRA instance A.  I have a local copy of JIRA and the script works just fine there.  We even made a dummy field that would spit out the cURL commands generated by the script (specifically the one in line 63), then tried executing those commands in command line on a local machine AND in bash on the server that hosts JIRA instance A.  The cURL command generated by the script works in both cases, it just doesn't work when we call curl.execute() (line 64) in the script.

We're not sure why it's working only outside of that specific instance of JIRA and were wondering if you have any clue as to what could be causing this.

Thank you for any help you can provide!


package clearleap

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor
import groovy.json.JsonSlurper


def curlCmd = "curl"
def username = "USERNAME"
def password = "PASSWORD"
def transitionName = "TRANSITION_NAME"
def protocol = "https://"


RemoteIssueLinkService linkService = ComponentManager.getComponentInstanceOfType(RemoteIssueLinkService.class)

String requestAuth = ""
String requestData = ""
String request = ""
String curl = ""
InputStream response;
Map responseObj;

def executeTransition = { RemoteIssueLink link ->
    String url = link.getUrl()
    if(!url || url.length() == 0 || !url.contains(protocol))

    String remoteBaseUrl = url.substring(0, url.indexOf("/", url.indexOf(protocol) + protocol.length()))
    String remoteIssueId = url.substring(url.lastIndexOf("/") + 1)

    request = "$remoteBaseUrl/rest/api/2/issue/$remoteIssueId/transitions"
    curl = "$curlCmd -u $username:$password $request"
    response = curl.execute().inputStream
    responseObj = new JsonSlurper().parse(response) as Map

    ArrayList<Map> transitions = responseObj.transitions as ArrayList<Map>
    String transitionId = null

    transitions.each { Map transition ->
        if( == transitionName) {
            transitionId =

    if(transitionId == null || transitionId.length() == 0)

    requestAuth = "Basic " + "$username:$password".bytes.encodeBase64()
    requestData = """
            \\"transition\\": {
                \\"id\\": \\"$transitionId\\"
    request = "$remoteBaseUrl/rest/api/2/issue/$remoteIssueId/transitions"
    curl = "$curlCmd -H \"Content-Type: application/json\" -H \"Authorization: $requestAuth\" -X POST -d \"$requestData\" -u $username:$password $request"

def loggedInUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def getLinksResult = linkService.getRemoteIssueLinksForIssue(loggedInUser, issue)

getLinksResult.getRemoteIssueLinks().forEach { RemoteIssueLink link ->

1 answer

I don't know... I would have guessed an SSL cert problem but if works from bash it should work from jira.

Did you try both curl commands including with the data that's it's supposed to send?

Capture the curl output with curl.execute().text, then log that. You might need to check the docs for the execute method to see if stdout and stderr goes to different places. curl -v may help too.

Another way is to install Fiddler, then tell curl to use a proxy which is the machine you install fiddler on, port 8888. Then you will see clearly what the issue is. But unless you can use http, not https, you have to dick around with certificates so you can effectively do a man-in-the-middle attack.


The native way to do this by the way is using HttpBuilder, which is included in SR. Not sure that that will help though, although the error reporting will be easier.

Thank you for the suggestions - I apologize for the late response, some competing priorities got in the way of our work on this.  Yes, we tried the commands with the data its supposed to send, and receive back the expected data in the response when run from bash.  We've seen this on two completely separate systems now, so we'll give some of the troubleshooting approaches you suggest a try.  Thanks again for the input and suggestions!

Thanks Jamie.  I have changed the script to use HTTPBuilder instead of cURL.  Much cleaner!  It looks like, however, I am running into a similar issue as this one:  Here is my HTTPBuilder setup:

def http = new HTTPBuilder(remoteUrl)
http.client.addRequestInterceptor(new HttpRequestInterceptor() {
    void process(HttpRequest httpRequest, HttpContext httpContext) {
        httpRequest.addHeader("Authorization", "Basic " + "$username:$password".bytes.encodeBase64().toString())
http.request(POST, JSON) { req ->
    headers.Accept = 'application/json'
    body = {
        transition {
            id: transitionId

For some reason I get a 400 Bad Request as well.

The error should be in the response entity... you can grab it by using a failure handler (or a debugging proxy). Have a look at the HttpBuilder docs.

I was able to find the error!!  I added a response.failure handler and printed out the details of the failure context.  For some reason, it was not setting the transition id to any value.  I looked at the JsonGroovyBuilder docs and tried setting body in several ways that should have been parsed correctly, but for some reason the transition id was always null, even if I hard-coded a value instead of using the transitionId variable.  Eventually, I just had to settle on using a raw string and it worked:

body = """
        "transition": {
            "id": "$transitionId"

Thanks Jamie, you were a great help in getting this done!


Tarun Sapra Community Leader Jul 22, 2016

Hi Irtiza,
Can you Please share the complete code sample for making http call from a post-function.


Hi Tarun, 

Here is the part of the script that revolves around making an HTTP POST request in a post-function.

First, we create an instance of HTTPBuilder, which is built into ScriptRunner.  The important part is adding the request interceptor so the target URL will authenticate properly.

def username = "USERNAME"
def password = "PASSWORD"
def getBuilder = {
    String url = "DESIRED URL TO PING"

    def http = new HTTPBuilder(url)
    http.client.addRequestInterceptor(new HttpRequestInterceptor() {
        void process(HttpRequest httpRequest, HttpContext httpContext) {
            httpRequest.addHeader("Authorization", "Basic " + "$username:$password".bytes.encodeBase64().toString())

    return http

Then, we use the HTTPBuilder object to ping the desired URL and get a response.  This is just a sample of what the body of the request should look like.

def http = getBuilder()

def result = http.request(POST, JSON) { req ->
    headers.Accept = 'application/json'
    body = """
            "transition": {
                "id": "$transitionId"

    response.success = { resp, json ->
        return json
    response.failure = { resp ->
        return resp.statusLine

If you are making a GET request, you can follow the same procedure, just change the request type from POST to GET.  The result will be a map object which you can parse accordingly.

Let me know if this helps.

syntax errors.... imports ?

Suggest an answer

Log in or Sign up to answer
Community showcase
Published in Jira Service Management

JSM June Challenge #2: Share how your business teams became ITSM rockstars

For JSM June Challenge #2, share how your non-technical teams like HR, legal, marketing, finance, and beyond started using Jira Service Management! Tell us: Did they ask to start using it or...

275 views 8 7
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you