zeroclaw-labs/zeroclaw · error · anyhow::Error

MiniMax OAuth refresh failed: {detail}

Error message

MiniMax OAuth refresh failed: {detail}

What it means

The MiniMax token endpoint returned HTTP 2xx with parseable JSON, but the payload's top-level `status` field is not "success" (case-insensitive). ZeroClaw reports base_resp.status_msg (or the status text itself). MiniMax signals soft failures through this status envelope rather than the HTTP status, so both layers are checked separately.

Source

Thrown at crates/zeroclaw-providers/src/lib.rs:491

        let detail = parsed
            .as_ref()
            .and_then(|payload| payload.base_resp.as_ref())
            .and_then(|base| base.status_msg.as_deref())
            .filter(|msg| !msg.trim().is_empty())
            .unwrap_or(body.as_str());
        anyhow::bail!("MiniMax OAuth refresh failed (HTTP {status}): {detail}");
    }

    if let Some(payload) = parsed {
        if let Some(status_text) = payload.status.as_deref()
            && !status_text.eq_ignore_ascii_case("success")
        {
            let detail = payload
                .base_resp
                .as_ref()
                .and_then(|base| base.status_msg.as_deref())
                .unwrap_or(status_text);
            anyhow::bail!("MiniMax OAuth refresh failed: {detail}");
        }
        if let Some(token) = payload
            .access_token
            .as_deref()
            .map(str::trim)
            .filter(|token| !token.is_empty())
        {
            return Ok(token.to_string());
        }
    }
    anyhow::bail!("MiniMax OAuth refresh response missing access_token")
}

fn resolve_qwen_oauth_context(credential_override: Option<&str>) -> QwenOauthProviderContext {
    let override_value = credential_override
        .map(str::trim)
        .filter(|value| !value.is_empty());
    let placeholder_requested = override_value

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Read status_msg — it carries the provider's real reason (token invalid, expired, rate limited)
  2. Refresh or reissue the oauth_refresh_token when status_msg indicates an invalid token
  3. Retry after a pause when status_msg indicates rate limiting
  4. Confirm the token belongs to the same account/region as the configured endpoint
Defensive patterns

Strategy: try-catch

Try / catch

match refresh_minimax_oauth_access_token(&token, &client_id, region) {
    Err(e) => {
        let msg = e.to_string();
        if msg.contains("rate") || msg.contains("limit") {
            retry_after(cooldown)
        } else {
            Reauth::required("reissue MiniMax oauth_refresh_token")
        }
    }
    ok => ok,
}

Prevention

When it happens

Trigger: Refresh response `{"status":"fail","base_resp":{"status_code":1004,"status_msg":"invalid refresh token"}}` with HTTP 200; any non-success status string (e.g. "error", "invalid_token").

Common situations: Expired or revoked MiniMax refresh tokens; tokens issued for a different app/region; rate-limit responses delivered in the success-shaped envelope.

Related errors


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