zeroclaw-labs/zeroclaw · error

Jira myself failed ({status}): {}

Error message

Jira myself failed ({status}): {}

What it means

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.

Source

Thrown at crates/zeroclaw-tools/src/jira_tool.rs:622

        let req = self
            .http
            .get(&url)
            .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 myself request failed"
            );
            anyhow::Error::msg(format!("Jira myself request failed: {e}"))
        })?;

        let status = resp.status();
        if !status.is_success() {
            let text = resp.text().await.unwrap_or_default();
            anyhow::bail!(
                "Jira myself 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 myself response"
            );
            anyhow::Error::msg(format!("Failed to parse Jira myself response: {e}"))
        })?;

        let shaped = json!({
            "accountId":    raw["accountId"],

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Create a fresh API token at id.atlassian.com and pass it together with the account email (Cloud)
  2. Verify the pair outside the agent: curl -u email:token "$BASE/rest/api/3/myself" must return 200
  3. Match the scheme to the deployment: email + token for Cloud, PAT only for Server/DC
  4. Trim whitespace and newlines from base_url, email, and token before constructing JiraTool

Example fix

// before: account password used as the token -> 401 on Cloud
JiraTool::new(
    "https://acme.atlassian.net".into(),
    Some("dev@acme.com".into()),
    account_password,
    actions,
    security,
    30,
)

// after: real API token from id.atlassian.com
JiraTool::new(
    "https://acme.atlassian.net".into(),
    Some("dev@acme.com".into()),
    api_token,
    actions,
    security,
    30,
)
Defensive patterns

Strategy: validation

Validate before calling

// startup gate: fail fast on bad credentials before any other Jira call
async fn require_jira_auth(jira: &JiraTool) -> anyhow::Result<()> {
    match jira.execute(serde_json::json!({"action": "myself"})).await {
        Ok(_) => Ok(()),
        Err(e) => Err(anyhow::anyhow!("Jira auth preflight failed: {e}")),
    }
}

Type guard

fn is_jira_myself_http_failure(err: &anyhow::Error) -> bool {
    err.to_string().starts_with("Jira myself failed (")
}

Try / catch

match jira.execute(myself_args).await {
    Ok(res) => res,
    Err(e) if is_jira_myself_http_failure(&e) => {
        let msg = e.to_string();
        if msg.starts_with("Jira myself failed (401") {
            hard_stop_fix_credentials(&msg) // all other actions will 401 too
        } else {
            return Err(e)
        }
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/ca7e25b8eed39333. Report an issue: GitHub.