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

MiniMax OAuth refresh failed (HTTP {status}): {detail}

Error message

MiniMax OAuth refresh failed (HTTP {status}): {detail}

What it means

refresh_minimax_oauth_access_token exchanges the configured MiniMax oauth_refresh_token for an access token at the region-specific token endpoint. A non-2xx HTTP status fails with the response's base_resp.status_msg text, or the raw body when that field is missing. Called during provider construction, before any chat request.

Source

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

                "minimax: OAuth refresh request failed"
            );
            anyhow::Error::msg(format!("MiniMax OAuth refresh request failed: {error}"))
        })?;

    let status = response.status();
    let body = response
        .text()
        .unwrap_or_else(|_| "<failed to read MiniMax OAuth response body>".to_string());
    let parsed = serde_json::from_str::<MinimaxOauthRefreshResponse>(&body).ok();

    if !status.is_success() {
        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())

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Obtain a fresh oauth_refresh_token from the MiniMax auth flow and update the profile
  2. Read status_msg in the message — it is the provider's own failure text and names the real cause
  3. For 5xx details, retry after a short wait before assuming credential failure
  4. Verify the configured region so the refresh hits the correct endpoint
Defensive patterns

Strategy: try-catch

Validate before calling

fn minimax_token_configured(api_key: Option<&str>) -> bool {
    api_key.map(|k| !k.trim().is_empty()).unwrap_or(false)
}

Try / catch

match refresh_minimax_oauth_access_token(&token, &client_id, region) {
    Err(e) if e.to_string().contains("HTTP 5") => retry_after(backoff),
    Err(e) => Err(e.context("MiniMax refresh token needs reissue")), // 4xx: credential problem
    ok => ok,
}

Prevention

When it happens

Trigger: POST of grant_type=refresh_token returning 400/401 (expired or revoked refresh_token), or 5xx during an upstream incident; response body echoed verbatim when base_resp.status_msg is absent.

Common situations: MiniMax refresh tokens expiring after long downtime; token copied with whitespace or truncation into config; region endpoint mismatch routing the refresh to the wrong geography.

Related errors


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