{"record":{"id":"1eda4079802c62e3","repo":"zeroclaw-labs/zeroclaw","slug":"transition-name-not-found-for-issue-key-ava","errorCode":null,"errorMessage":"Transition '{name}' not found for {issue_key}. Available: {}","messagePattern":"Transition '(.+?)' not found for (.+?)\\. Available: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/jira_tool.rs","lineNumber":774,"sourceCode":"            (_, Some(name)) if !name.trim().is_empty() => {\n                let transitions = self.fetch_transitions(issue_key).await?;\n                let needle = name.trim().to_ascii_lowercase();\n                let found = transitions.iter().find_map(|t| {\n                    let n = t[\"name\"].as_str()?;\n                    if n.eq_ignore_ascii_case(&needle) || n.to_ascii_lowercase() == needle {\n                        t[\"id\"].as_str().map(String::from)\n                    } else {\n                        None\n                    }\n                });\n                match found {\n                    Some(id) => id,\n                    None => {\n                        let available: Vec<&str> = transitions\n                            .iter()\n                            .filter_map(|t| t[\"name\"].as_str())\n                            .collect();\n                        anyhow::bail!(\n                            \"Transition '{name}' not found for {issue_key}. Available: {}\",\n                            available.join(\", \")\n                        );\n                    }\n                }\n            }\n            _ => {\n                anyhow::bail!(\n                    \"transition_ticket requires exactly one of transition_id or transition_name\"\n                );\n            }\n        };\n\n        let ver = self.api_version();\n        let url = format!(\n            \"{}/rest/api/{}/issue/{}/transitions\",\n            self.base_url, ver, issue_key\n        );","sourceCodeStart":756,"sourceCodeEnd":792,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/jira_tool.rs#L756-L792","documentation":"Thrown by transition_ticket when resolving a transition by name: the tool fetched the issue's available transitions, case-insensitively matched each name against the requested transition_name, and found no match. The message lists every transition name actually available on the issue, which reflects the issue's current workflow status. This is a client-side resolution failure before any POST is made.","triggerScenarios":"Calling transition_ticket with a name like \"Done\" when the issue's current status only offers e.g. \"In Progress\", \"In Review\"; using a workflow-specific name (\"Close Issue\") from a different workflow scheme; trailing/leading whitespace is trimmed but different wording (\"Resolve\" vs \"Resolved\") will not match.","commonSituations":"Hardcoding transition names from one project's workflow into scripts reused on another project; the issue is already in the target status so the transition no longer applies; Jira Cloud workflows renamed by admins; localized or custom workflow steps (e.g. Jira Service Management queues) that differ from software-project defaults.","solutions":["Read the 'Available:' list in the error and re-run with one of those exact names (matching is case-insensitive).","Call list_transitions(issue_key) first and select the id or name dynamically instead of hardcoding.","If the transition should exist, check the issue's current status in Jira — the workflow may not allow this transition from that status.","Prefer transition_id over name for scripted automation, since ids are stable per workflow while names can be renamed.","If projects use different workflows, make the transition name a per-project configuration value."],"exampleFix":"// before\njira.transition_ticket(\"PROJ-42\", None, Some(\"Done\")).await?; // workflow says \"Close Issue\"\n\n// after\nlet result = jira.list_transitions(\"PROJ-42\").await?;\n// pick from the returned transitions, e.g. the one whose `to_status` is what you want\njira.transition_ticket(\"PROJ-42\", None, Some(\"Close Issue\")).await?;","handlingStrategy":"validation","validationCode":"// Fetch transitions first and match the name yourself before calling transition_ticket\nlet transitions = jira.list_transitions(\"PROJ-42\").await?; // returns {transitions:[{id,name,to_status}]}\nlet wanted = \"done\"; // desired target, lowercase\nlet chosen = transitions.iter().find(|t| {\n    t[\"name\"].as_str().map(|n| n.to_ascii_lowercase().contains(wanted)).unwrap_or(false)\n});\nif chosen.is_none() {\n    anyhow::bail!(\"no transition leads to {wanted}; issue may already be there\");\n}\nlet name = chosen.unwrap()[\"name\"].as_str().unwrap();","typeGuard":null,"tryCatchPattern":"match jira.transition_ticket(\"PROJ-42\", None, Some(name)).await {\n    Ok(_) => {}\n    Err(e) if e.to_string().starts_with(\"Transition '\") => {\n        // workflow moved on: re-fetch transitions and retry once with a fresh pick\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never hardcode transition names across projects; resolve them per issue via list_transitions.","Match on to_status rather than the transition name when you care about the destination state.","Remember matching is case-insensitive but exact-word: 'Done' != 'Close Issue'."],"tags":["jira","workflow","transitions","name-resolution"],"backgroundTag":"invalid-workflow-transition","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}