zeroclaw-labs/zeroclaw · error
Jira list_transitions failed ({status}): {}
Error message
Jira list_transitions failed ({status}): {} What it means
Thrown when the Jira REST endpoint GET /rest/api/{ver}/issue/{key}/transitions returns a non-2xx HTTP status. The tool validates the issue key locally first, then sends an authenticated request; any error status (401, 403, 404, 500...) causes the response body (truncated to MAX_ERROR_BODY_CHARS) to be embedded in this error. The status code and body text identify the upstream Jira failure.
Source
Thrown at crates/zeroclaw-tools/src/jira_tool.rs:713
let req = self
.http
.get(&url)
.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 list_transitions request failed"
);
anyhow::Error::msg(format!("Jira list_transitions request failed: {e}"))
})?;
let status = resp.status();
if !status.is_success() {
let text = resp.text().await.unwrap_or_default();
anyhow::bail!(
"Jira list_transitions failed ({status}): {}",
crate::util_helpers::truncate_with_ellipsis(&text, MAX_ERROR_BODY_CHARS)
);
}
let raw: Value = resp.json().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: Failed to parse Jira transitions response"
);
anyhow::Error::msg(format!("Failed to parse Jira transitions response: {e}"))
})?;
Ok(shape_transitions(&raw))
}View on GitHub (pinned to 88bb9c8533)
Solutions
- Check the status code in the message: 404 means the issue key is wrong or invisible to this user, 401/403 means authentication/permission, 5xx means retry later.
- Verify the issue exists by opening {base_url}/browse/{issue_key} in a browser as the same user the token belongs to.
- Re-check the Jira auth config (Bearer token/API token/email) used by the tool and refresh it if expired.
- Confirm base_url matches your instance (e.g. https://yourco.atlassian.net for Cloud) and that the instance supports the API version the tool selected.
- For transient 5xx, retry the call after a short backoff.
Example fix
// before
jira.transition_ticket("PROJ-42", None, Some("Done")).await?; // key was typo'd PRJ-42 -> 404
// after
// verify the issue is reachable first
jira.get_ticket("PROJ-42").await?;
jira.transition_ticket("PROJ-42", None, Some("Done")).await?; Defensive patterns
Strategy: try-catch
Try / catch
// Rust: match on the Result and branch by embedded status
match jira.list_transitions("PROJ-42").await {
Ok(res) => handle(res),
Err(e) => {
let msg = e.to_string();
if msg.contains("(404") {
// issue missing or invisible: stop, surface to user
} else if msg.contains("(401") || msg.contains("(403") {
// credentials/permission: refresh token or alert admin
} else if msg.contains("(50") {
// server-side: safe to retry with backoff
}
}
} Prevention
- Confirm the issue key exists with get_ticket before transitioning by name (which triggers a transitions fetch).
- Keep Jira credentials in a secret store with rotation so 401s surface as config events, not runtime surprises.
- Treat 5xx as transient: retry with exponential backoff, never retry 4xx immediately.
When it happens
Trigger: Calling jira list_transitions or transition_ticket (by name, which fetches transitions first) where the issue does not exist (404), the credentials/token are bad or expired (401), the user lacks browse permission on the project (403), or Jira Cloud/server returns a 5xx or malformed request (400 with a bad API version).
Common situations: Issue key typo'd but still passing the PROJECT-123 format check; Jira PAT/API token expired or revoked; base_url pointing at the wrong Jira instance (Cloud vs Server URL confusion); the issue was deleted or in a restricted project; API version 2 vs 3 mismatch on Server instances that lack /rest/api/3.
Related errors
- Jira get_ticket failed ({status}): {}
- Jira transition_ticket failed ({status}): {}
- Jira search_tickets failed ({status}): {}
- Jira comment_ticket failed ({status}): {}
- Jira list_projects failed ({status}): {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/257d86534ab20ddb.
Report an issue: GitHub.