{"record":{"id":"257d86534ab20ddb","repo":"zeroclaw-labs/zeroclaw","slug":"jira-list-transitions-failed-status","errorCode":null,"errorMessage":"Jira list_transitions failed ({status}): {}","messagePattern":"Jira list_transitions failed \\((.+?)\\): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/jira_tool.rs","lineNumber":713,"sourceCode":"        let req = self\n            .http\n            .get(&url)\n            .timeout(std::time::Duration::from_secs(self.timeout_secs));\n        let resp = self.authenticated(req).send().await.map_err(|e| {\n            ::zeroclaw_log::record!(\n                ERROR,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                    .with_attrs(::serde_json::json!({\"error\": format!(\"{}\", e)})),\n                \"jira: Jira list_transitions request failed\"\n            );\n            anyhow::Error::msg(format!(\"Jira list_transitions request failed: {e}\"))\n        })?;\n\n        let status = resp.status();\n        if !status.is_success() {\n            let text = resp.text().await.unwrap_or_default();\n            anyhow::bail!(\n                \"Jira list_transitions failed ({status}): {}\",\n                crate::util_helpers::truncate_with_ellipsis(&text, MAX_ERROR_BODY_CHARS)\n            );\n        }\n\n        let raw: Value = resp.json().await.map_err(|e| {\n            ::zeroclaw_log::record!(\n                ERROR,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                    .with_attrs(::serde_json::json!({\"error\": format!(\"{}\", e)})),\n                \"jira: Failed to parse Jira transitions response\"\n            );\n            anyhow::Error::msg(format!(\"Failed to parse Jira transitions response: {e}\"))\n        })?;\n\n        Ok(shape_transitions(&raw))\n    }","sourceCodeStart":695,"sourceCodeEnd":731,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/jira_tool.rs#L695-L731","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\njira.transition_ticket(\"PROJ-42\", None, Some(\"Done\")).await?; // key was typo'd PRJ-42 -> 404\n\n// after\n// verify the issue is reachable first\njira.get_ticket(\"PROJ-42\").await?;\njira.transition_ticket(\"PROJ-42\", None, Some(\"Done\")).await?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust: match on the Result and branch by embedded status\nmatch jira.list_transitions(\"PROJ-42\").await {\n    Ok(res) => handle(res),\n    Err(e) => {\n        let msg = e.to_string();\n        if msg.contains(\"(404\") {\n            // issue missing or invisible: stop, surface to user\n        } else if msg.contains(\"(401\") || msg.contains(\"(403\") {\n            // credentials/permission: refresh token or alert admin\n        } else if msg.contains(\"(50\") {\n            // server-side: safe to retry with backoff\n        }\n    }\n}","preventionTips":["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."],"tags":["jira","http-status","rest-api","transitions"],"backgroundTag":"http-error-response","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}