zeroclaw-labs/zeroclaw · error
Jira search_tickets failed ({status}): {}
Error message
Jira search_tickets failed ({status}): {} What it means
Thrown when the Jira Cloud search call (POST {base_url}/rest/api/3/search with JQL, page size 100) returns non-2xx; search_tickets dispatches to this v3 path whenever an email is configured. The truncated body (500 chars) is inlined. Frequent causes: 400 invalid JQL (syntax, unknown field or function), 401/403 credential problems, or 404/gone when Atlassian removes or changes the Cloud REST search endpoint.
Source
Thrown at crates/zeroclaw-tools/src/jira_tool.rs:224
.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 search_tickets request failed"
);
anyhow::Error::msg(format!("Jira search_tickets request failed: {e}"))
})?;
let status = resp.status();
if !status.is_success() {
let text = resp.text().await.unwrap_or_default();
anyhow::bail!(
"Jira search_tickets 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 search response"
);
anyhow::Error::msg(format!("Failed to parse Jira search response: {e}"))
})?;
if let Some(page) = raw["issues"].as_array() {
issues.extend(page.iter().map(shape_basic_search));View on GitHub (pinned to 88bb9c8533)
Solutions
- Paste the exact JQL into Jira's advanced search in the web UI to get its precise error
- Fix quoting: wrap phrases in double quotes, escape embedded quotes, and check field names against /rest/api/3/field
- If the message shows 404/410 with a 'removed' body, upgrade zeroclaw-tools - the endpoint contract changed
- On 401/403 verify email + token with the myself action before debugging JQL
Example fix
// before: raw user phrase passed as JQL -> HTTP 400
{"action": "search_tickets", "query": "summary ~ ship it now"}
// after: quote the phrase so the JQL parses
{"action": "search_tickets", "query": "summary ~ \"ship it now\""} Defensive patterns
Strategy: try-catch
Validate before calling
// cheap JQL sanity check before the call
fn jql_looks_valid(q: &str) -> bool {
let q = q.trim();
!q.is_empty() && q.matches('"').count() % 2 == 0
} Type guard
fn is_jira_search_http_failure(err: &anyhow::Error) -> bool {
err.to_string().starts_with("Jira search_tickets failed (")
} Try / catch
match jira.execute(search_args).await {
Ok(res) => res,
Err(e) if is_jira_search_http_failure(&e) => {
let msg = e.to_string();
if msg.contains("(400") {
surface_jql_error(&msg) // body carries Atlassian's JQL message
} else if msg.contains("(401") || msg.contains("(403") {
refresh_credentials()
} else {
return Err(e)
}
}
Err(e) => return Err(e),
} Prevention
- Quote and escape dynamic JQL fragments before invoking search_tickets
- Prefer field IDs over custom-field names in stored JQL
- Track Atlassian search-endpoint deprecations and keep zeroclaw-tools current
- Cache /rest/api/3/field names once per session to catch renames early
When it happens
Trigger: search_tickets with malformed JQL - unbalanced quotes, unescaped reserved words, or a custom field referenced by a name that does not exist in the site; an empty query string; or an Atlassian-side endpoint change where /rest/api/3/search answers 404/410 for the pinned zeroclaw-tools version.
Common situations: Agents building JQL from raw user input with unescaped double quotes; sites where custom fields were renamed after JQL templates were written; Atlassian deprecating older search endpoints so an older zeroclaw-tools build starts failing until upgraded.
Related errors
- Jira get_ticket failed ({status}): {}
- Jira comment_ticket failed ({status}): {}
- Jira list_projects failed ({status}): {}
- Jira list_projects users failed ({status}): {}
- statuses request returned {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/28999d8f381311b3.
Report an issue: GitHub.