zeroclaw-labs/zeroclaw · error
Jira comment_ticket failed ({status}): {}
Error message
Jira comment_ticket failed ({status}): {} What it means
POST {base_url}/rest/api/{2|3}/issue/{key}/comment answered non-2xx; the truncated body is inlined. This is reached only after the local allowed_actions gate permitted the comment action, so the failure is server-side: 403 the token user lacks Comment permission or the workflow blocks it, 400 invalid or empty body (v3 expects valid ADF content), 404 unknown issue, 401 credentials.
Source
Thrown at crates/zeroclaw-tools/src/jira_tool.rs:375
.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 comment_ticket request failed"
);
anyhow::Error::msg(format!("Jira comment_ticket request failed: {e}"))
})?;
let status = resp.status();
if !status.is_success() {
let text = resp.text().await.unwrap_or_default();
anyhow::bail!(
"Jira comment_ticket failed ({status}): {}",
crate::util_helpers::truncate_with_ellipsis(&text, MAX_ERROR_BODY_CHARS)
);
}
let response: 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 comment response"
);
anyhow::Error::msg(format!("Failed to parse Jira comment response: {e}"))
})?;
let shaped = shape_comment_response(&response);
Ok(ToolResult {View on GitHub (pinned to 88bb9c8533)
Solutions
- Read the status in the message: 403 -> grant the bot Add Comments permission on the project; 400 -> simplify and shorten the comment text; 404 -> verify the issue key
- Open the issue in the web UI and comment as the same bot user to see the exact restriction
- Confirm comment_ticket is in allowed_actions and the token user can browse the project
- If the workflow blocks comments in the current status, transition the issue first or relax the validator
Example fix
// before: empty comment body sneaks through to an HTTP 400
{"action": "comment_ticket", "ticket": "ACME-7", "comment": ""}
// after: guard the argument before invoking the tool
let comment = args["comment"].as_str().unwrap_or("").trim();
if comment.is_empty() {
return Err(anyhow::anyhow!("comment must be non-empty"));
} Defensive patterns
Strategy: validation
Validate before calling
// caller-side pre-check before comment_ticket
fn comment_args_valid(args: &serde_json::Value) -> bool {
args.get("ticket").and_then(|v| v.as_str()).is_some_and(valid_issue_key)
&& args
.get("comment")
.and_then(|v| v.as_str())
.is_some_and(|c| !c.trim().is_empty())
} Type guard
fn is_jira_comment_http_failure(err: &anyhow::Error) -> bool {
err.to_string().starts_with("Jira comment_ticket failed (")
} Try / catch
match jira.execute(comment_args).await {
Ok(res) => res,
Err(e) if is_jira_comment_http_failure(&e) => {
let msg = e.to_string();
if msg.starts_with("Jira comment_ticket failed (403") {
queue_for_human_review(&msg) // permission problem: do not retry
} else {
return Err(e)
}
}
Err(e) => return Err(e),
} Prevention
- Validate a non-empty comment and a well-formed issue key before the call
- Grant bot users the minimum permission set (Browse Projects + Add Comments) explicitly
- Keep comment text plain and under Jira body limits
- Track which workflow statuses disallow comments and transition first
When it happens
Trigger: comment_ticket on an issue whose workflow validator forbids commenting or whose resolved screen rejects the body (400); a token user without the Add Comments project permission (403); commenting on an issue key that belongs to another site (404).
Common situations: Bot users added to projects as viewers only; comments attempted on closed issues in restricted workflows; agents composing very long or emoji-heavy comments that the v3 ADF conversion rejects; issues moved between projects breaking cached keys.
Related errors
- Jira list_projects users failed ({status}): {}
- Jira get_ticket failed ({status}): {}
- Jira search_tickets failed ({status}): {}
- Jira list_projects failed ({status}): {}
- statuses request returned {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/8db77040601232de.
Report an issue: GitHub.