Change Request status not syncing from Jira Cloud to Jira On-Premise (no error shown)

From Customer:

Hi all,

We have a Jira Cloud ↔ Jira On-Premise connection set up with Exalate. It syncs Incidents, Service Requests and Change Requests. Incidents and Service Requests have been working fine for a long time.

We recently added Change Request to the same connection, reusing the same Incoming sync rule structure that already worked for Service Request (just adjusted for the Change Request status names). Summary, description, comments and attachments all sync correctly for Change Request tickets. But when we change the Status on the Jira Cloud side, the Status on the Jira On-Premise side never updates.

The strange part: there is no error anywhere. No entry in Entity Sync Status, nothing obviously wrong in the support.zip either. The sync just “completes” and nothing happens to the Status field.

Has anyone run into something similar? Where else should we be looking, since there’s no error to go on?

Thanks!

It sounds like your sync is working for most fields, but the status isn’t updating for Change Requests, and there are no errors to help diagnose. This is a common scenario when the status mapping or workflow transitions aren’t fully aligned between the two Jira instances.

Here are some steps and checks you can perform:

  1. Status Mapping in Sync Rules
    Double-check your sync rules for Change Requests, especially the part where you map or set the status. The status names must match exactly what’s available in the destination Jira workflow. If the status name in Jira Cloud doesn’t exist or isn’t available for transition in Jira On-Premise, the status won’t update, but Exalate won’t throw an error—it just skips the update.

  2. Workflow Transitions
    Ensure that the user account used by Exalate on Jira On-Premise has permission to perform the required status transitions for Change Requests. Also, verify that the workflow for Change Requests allows transitions from the current status to the target status. If a direct transition isn’t possible, the status won’t change.

  3. Sync Rule Example
    A typical status sync in the incoming sync script might look like this:

if (issue.status && issue.status != replica.status) {
    def transition = nodeHelper.getTransition(issue, replica.status)
    if (transition) {
        issue.transitionTo(transition)
    }
}

Make sure your script is referencing the correct status names and using the right logic for Change Requests.

  1. Logging and Debugging
    Since there are no errors, try adding custom logging to your sync rules to see what values are being processed for status and whether the transition logic is being triggered.

  2. Documentation Reference
    You can find more details on syncing statuses and troubleshooting workflow transitions here:
    https://docs.exalate.com/docs/syncing-statuses

If you’ve checked all of the above and the issue persists, it may help to temporarily simplify your sync rule for Change Requests to only sync the status, and see if that works—then gradually add back other logic.

Let me know if you need a sample sync rule or further troubleshooting steps!

This exact symptom - “sync completes, Status field silently does nothing, zero errors” - is almost always caused by the incoming sync rule failing to match on the issue type, so the whole status-mapping block for that type gets skipped without ever throwing anything.

Check the actual system type name your Incoming sync rule is comparing against. If your script branches on something like:

if (replica.type?.name?.equalsIgnoreCase("[System] Service request")) { ... }
else if (replica.type?.name?.equalsIgnoreCase("[System] Change Request")) { ... }
else if (replica.type?.name?.equalsIgnoreCase("[System] Incident")) { ... }

double-check the exact string your remote system sends for that issue type. In our case it turned out to be “[System] Change”, not “[System] Change Request”. Because the comparison never matched, the entire status-mapping block for that type was skipped every single time - no exception, just a silent no-op, because the script fell through to a generic else with only a log.info() call (which you’d only ever see by digging through support.zip).

The fastest way to confirm this without downloading support.zip repeatedly: temporarily add a debug.error() call (from the built-in debugHelper) right at the top of that block, instead of log.info(), e.g.:

debug.error("replica.type.name = [" + replica.type?.name + "]")

Unlike log.info, debug.error() throws a visible sync error carrying your message straight into the tab: Error in the UI. It does block that one issue’s sync until you Resolve & Retry it, but for a single diagnostic check that’s a small price for not having to generate and grep through a support.zip. Once you can see the actual type name being sent, fix the comparison to match it exactly, then remove the debug.error() line - otherwise it’ll keep blocking every future sync on that connection.

Recommended Changes:

  1. Ticket type check (Change Request was never being recognized)

BEFORE:

else if (replica.type?.name?.equalsIgnoreCase("[System] Change Request")){ ... }

AFTER:

else if (replica.type?.name?.equalsIgnoreCase("[System] Change")){ ... }

Why: Jira Cloud sends the internal type name as “[System] Change”, not “[System] Change Request”. The old check could never match, so this whole block of code (which handles the status mapping) was always skipped for Change Request tickets, without any error being shown.

  1. Status name matching (case sensitivity)

BEFORE:

def remoteStatusName = replica.status.name issue.setStatus(statusMap[remoteStatusName] ?: remoteStatusName)

AFTER:

def lookupStatusCaseInsensitive = { Map map, String remoteName -> if (remoteName == null) return null def match = map.find { key, value -> key.equalsIgnoreCase(remoteName.trim()) } return match ? match.value : null } ... def remoteStatusName = replica.status.name def targetStatusName = lookupStatusCaseInsensitive(statusMap, remoteStatusName) ?: remoteStatusName issue.setStatus(targetStatusName)

--

Kind regards,

Ashar