zeroclaw-labs/zeroclaw · error

Jira transition_ticket failed ({status}): {}

Error message

Jira transition_ticket failed ({status}): {}

What it means

Thrown when POST {base_url}/rest/api/{ver}/issue/{key}/transitions returns a non-2xx status after the tool resolved a transition id and submitted {"transition":{"id":...}}. A 204 is the success path, so any error status (typically 400) means Jira rejected the transition itself. The truncated response body usually names the exact problem.

Source

Thrown at crates/zeroclaw-tools/src/jira_tool.rs:814

            .http
            .post(&url)
            .json(&body)
            .timeout(std::time::Duration::from_secs(self.timeout_secs));
        let resp = self.authenticated(req).send().await.map_err(|e| {
            ::zeroclaw_log::record!(
                ERROR,
                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
                    .with_outcome(::zeroclaw_log::EventOutcome::Failure)
                    .with_attrs(::serde_json::json!({"error": format!("{}", e)})),
                "jira: Jira transition_ticket request failed"
            );
            anyhow::Error::msg(format!("Jira transition_ticket request failed: {e}"))
        })?;

        let status = resp.status();
        if !status.is_success() {
            let text = resp.text().await.unwrap_or_default();
            anyhow::bail!(
                "Jira transition_ticket failed ({status}): {}",
                crate::util_helpers::truncate_with_ellipsis(&text, MAX_ERROR_BODY_CHARS)
            );
        }

        // Jira returns 204 No Content on a successful transition.
        let output = json!({
            "ok": true,
            "issue_key": issue_key,
            "transition_id": resolved_id,
        });
        Ok(ToolResult {
            success: true,
            output: serde_json::to_string_pretty(&output)
                .unwrap_or_else(|_| output.to_string())
                .into(),
            error: None,
        })

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Read the Jira body in the message — 'It isn't possible to transition' style errors mean the id is stale; re-fetch with list_transitions and retry with a fresh id.
  2. If a workflow validator demands fields, supply them via the Jira API directly or transition manually once to see the required inputs.
  3. For 401/403, verify the token and the user's transition permission in the project's permission scheme.
  4. Add concurrency protection (lock or re-check current status right before transitioning) when multiple writers touch the issue.

Example fix

// before
jira.transition_ticket("PROJ-42", Some(cached_id), None).await?; // cached_id stale after workflow edit

// after
// always resolve fresh at call time
let transitions = jira.list_transitions("PROJ-42").await?;
let id = /* find desired transition id in `transitions` */;
jira.transition_ticket("PROJ-42", Some(id), None).await?;
Defensive patterns

Strategy: try-catch

Try / catch

// Stale-id race: one re-fetch + retry, then give up
match jira.transition_ticket(key, Some(&id), None).await {
    Ok(_) => Ok(()),
    Err(e) if e.to_string().starts_with("Jira transition_ticket failed (4") => {
        // 4xx from Jira: id may be stale or blocked by a validator
        let _ = jira.list_transitions(key).await?; // re-check availability
        Err(e).context("transition rejected; re-inspect available transitions")
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Posting a transition id that is valid in the workflow but not available from the issue's current status (400 'transition is not valid'); racing another user/process that already moved the issue; transition ids fetched long ago that changed after a workflow edit; 401/403 when the user lacks transition permission.

Common situations: Automation caching transition ids across workflow updates; two automations transitioning the same issue concurrently; permissions schemes that allow viewing but not transitioning an issue; Jira Cloud workflow validators (e.g. required fields on transition) rejecting the POST.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/542286763bf96799. Report an issue: GitHub.