{"record":{"id":"ca7e25b8eed39333","repo":"zeroclaw-labs/zeroclaw","slug":"jira-myself-failed-status","errorCode":null,"errorMessage":"Jira myself failed ({status}): {}","messagePattern":"Jira myself failed \\((.+?)\\): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/jira_tool.rs","lineNumber":622,"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 myself request failed\"\n            );\n            anyhow::Error::msg(format!(\"Jira myself 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 myself 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 myself response\"\n            );\n            anyhow::Error::msg(format!(\"Failed to parse Jira myself response: {e}\"))\n        })?;\n\n        let shaped = json!({\n            \"accountId\":    raw[\"accountId\"],","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/jira_tool.rs#L604-L640","documentation":"GET {base_url}/rest/api/{2|3}/myself returned non-2xx; the truncated body is inlined. This endpoint is the canonical credential probe: 401 means the email:token pair (Cloud, HTTP Basic) or the PAT (Server/DC, Bearer) is wrong; 403 can indicate a login challenge or captcha; 404 usually means base_url is not a Jira site root.","triggerScenarios":"get_myself with a mistyped or revoked Atlassian API token, an account password used where an API token is required, an omitted email on Cloud (the tool falls back to v2 + Bearer, which Cloud rejects with 401), or a base_url pointing at a non-Jira host so the path 404s.","commonSituations":"First-run setup mistakes (wrong site slug, stale docs); tokens invalidated by password resets or org policy; Atlassian rejecting Basic auth with account passwords - only API tokens work; trailing whitespace in secrets.","solutions":["Create a fresh API token at id.atlassian.com and pass it together with the account email (Cloud)","Verify the pair outside the agent: curl -u email:token \"$BASE/rest/api/3/myself\" must return 200","Match the scheme to the deployment: email + token for Cloud, PAT only for Server/DC","Trim whitespace and newlines from base_url, email, and token before constructing JiraTool"],"exampleFix":"// before: account password used as the token -> 401 on Cloud\nJiraTool::new(\n    \"https://acme.atlassian.net\".into(),\n    Some(\"dev@acme.com\".into()),\n    account_password,\n    actions,\n    security,\n    30,\n)\n\n// after: real API token from id.atlassian.com\nJiraTool::new(\n    \"https://acme.atlassian.net\".into(),\n    Some(\"dev@acme.com\".into()),\n    api_token,\n    actions,\n    security,\n    30,\n)","handlingStrategy":"validation","validationCode":"// startup gate: fail fast on bad credentials before any other Jira call\nasync fn require_jira_auth(jira: &JiraTool) -> anyhow::Result<()> {\n    match jira.execute(serde_json::json!({\"action\": \"myself\"})).await {\n        Ok(_) => Ok(()),\n        Err(e) => Err(anyhow::anyhow!(\"Jira auth preflight failed: {e}\")),\n    }\n}","typeGuard":"fn is_jira_myself_http_failure(err: &anyhow::Error) -> bool {\n    err.to_string().starts_with(\"Jira myself failed (\")\n}","tryCatchPattern":"match jira.execute(myself_args).await {\n    Ok(res) => res,\n    Err(e) if is_jira_myself_http_failure(&e) => {\n        let msg = e.to_string();\n        if msg.starts_with(\"Jira myself failed (401\") {\n            hard_stop_fix_credentials(&msg) // all other actions will 401 too\n        } else {\n            return Err(e)\n        }\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Run get_myself as a startup health check and after any 401 from another action","Source email/token/base_url from one secret store and trim on load","Use API tokens, never account passwords, for Cloud Basic auth","Rotate tokens on a schedule and update config atomically"],"tags":["rust","zeroclaw","jira","authentication","http-status","credentials"],"backgroundTag":"jira-rest-api-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}