Jira Cloud REST API: Unable to add comment via ADF, receiving "Comment body is not valid!"
Asked by Martin Fredrich:

Hi Community,  

I am facing an issue when trying to add a comment via the Jira Cloud REST API using the ADF (Atlassian Document Format). Despite following the correct ADF format and attempting both v2 and v3 API endpoints, I consistently receive the error:
> **"Comment body is not valid!"**

#### Steps Taken: {#toc-hId-372753069}

1. **API Endpoints Tried**:

   * /rest/api/3/issue/{issueKey}/comment (v3)

   * /rest/api/2/issue/{issueKey}/comment (v2)

2. **Code Used** :  
   The following Groovy script is used to add comments to linked issues. The script executes without errors, and the logging indicates that the API requests are made successfully. However, the comments are not added to the issues, and the API returns the error mentioned above.

       import groovy.json.JsonOutputdef issueKey = issue.key // Stores the key of the current Jira issuedef scriptCommentTag = "AutomatedComment" // Tag to identify comments created by the script to prevent loops// Fetch details of the current issue via the Jira REST APIdef response = get('/rest/api/3/issue/' + issueKey)        .header('Content-Type', 'application/json')        .asObject(Map)// Log information about the issuelogger.info("Issue id: " + response.body.id)logger.info("Priority name: " + response.body.fields.priority.name)logger.info("Inward issue links: " + response.body.fields.issuelinks*.inwardIssue.key)logger.info("Outward issue links: " + response.body.fields.issuelinks*.outwardIssue.key)// Iterate through all linked issues (inward and outward)response.body.fields.issuelinks.each { it ->    if (it.inwardIssue) {        logger.info("Inward issue: " + it.inwardIssue.key)        addComment(issueKey, it.inwardIssue.key, scriptCommentTag)    } else if (it.outwardIssue) {        logger.info("Outward issue: " + it.outwardIssue.key)        addComment(issueKey, it.outwardIssue.key, scriptCommentTag)    }}// Function to add a comment to a linked issuedef addComment(originalIssue, linkedIssue, scriptCommentTag) {    // Fetch the last comment from the original issue    def commentResponse = get("/rest/api/3/issue/${originalIssue}/comment")            .header('Content-Type', 'application/json')            .asObject(Map)    // Extract the last comment in ADF format    def lastComment = commentResponse.body.comments[-1].body    // Check if the comment was already added by this script (to prevent loops)    if (JsonOutput.toJson(lastComment).contains(scriptCommentTag)) {        logger.info("Comment already added by the script, no action required.")        return    }    // Append a new paragraph with the tag `AutomatedComment` to the comment    lastComment.content << [        type: "paragraph",        content: [            [                type: "text",                text: " [" + scriptCommentTag + "]"            ]        ]    ]    // Serialize the updated comment to JSON    def serializedAdfComment = JsonOutput.toJson(lastComment)    // Send the new comment to the linked issue    def result = post("/rest/api/2/issue/${linkedIssue}/comment") // Using the v2 API endpoint            .header('Content-Type', 'application/json')            .body([                body: serializedAdfComment // Pass the comment as JSON            ])            .asString()    // Check if the comment was added successfully    if (result.status == 201) {        logger.info("Comment successfully added to: " + linkedIssue)    } else {        logger.error("Error adding comment to: " + linkedIssue + " - Status: " + result.status + " - Error: " + result.body)    }}

3. **Observed Behavior**:

   * The script runs without throwing exceptions.

   * The API calls return a 400 Bad Request error with the message:

         {  "errorMessages": [],  "errors": {    "comment": "Comment body is not valid!"  }}

   * The comments are not added to the linked issues.

4. **Output Format** :  
   The serialized ADF comment that is being sent in the API request looks like this:  

    {  "type": "doc",  "version": 1,  "content": [    {      "type": "paragraph",      "content": [        {          "type": "text",          "text": "Hallo Welt!"        }      ]    },    {      "type": "paragraph",      "content": [        {          "type": "text",          "text": " [AutomatedComment]"        }      ]    }  ]}

1.
   * This format appears to be correct based on the ADF documentation, yet the API still rejects it.

     **Attempts Made**:
     * Tried both v2 and v3 API endpoints.

     * Modified the structure of the ADF comment based on examples from the Atlassian Community.

     * Used hardcoded text in the comment to rule out issues with dynamic content.

     * Referenced the bug report [JSWCLOUD-18945](https://jira.atlassian.com/browse/JSWCLOUD-18945) and attempted the suggested workaround (using v2 API), but the issue persists.

#### Expected Behavior: {#toc-hId--1434701394}

* The comment should be successfully added to the linked Jira issue without triggering the "Comment body is not valid!" error.

* The comment should appear in the issue with the correct formatting, as specified in the ADF structure.

Is there an additional requirement or known issue with the Jira Cloud REST API regarding comments in ADF format?

Any assistance in resolving this issue would be greatly appreciated.

Thank you for your support.

Best regards  
Martin


Answers:
author: Martin Fredrich
body: **Resolution Details:**

The core of the solution was correctly formatting the ADF comment body. By following this example from the Atlassian Support, we were able to ensure that the API correctly accepted the comment, and the error"Comment body is not valid!" no longer occurred.

```
{
"body": 
{ "content": [
?   { "content": [
        { "text": "This is a valid ADF formatted comment.",
          "type": "text" }
           ], 
           "type": "paragraph"
        }
       ], 
       "type": "doc", 
       "version": 1 
     } 
}
```


Tags: cloud

jira-cloud

script-listener

scriptrunner