Hmbown/CodeWhale · error
OAuth revoke failed with HTTP
Error message
{} OAuth revoke failed with HTTP {status}: {} What it means
Thrown when the revocation endpoint replies with a non-2xx HTTP status. The body is compacted via `compact_form_error` so the developer sees a short reason (OAuth error code or truncated body) alongside the status.
Solutions
- Verify the client_id matches the one that obtained the token (revoke endpoints reject mismatched clients)
- Read the compacted body in the message for the OAuth error code (e.g. invalid_client, unsupported_token_type)
- If the token was already revoked, treat a 400 as success and clear local state
- Retry on 5xx; investigate provider status if persistent
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure client_id matches the issuing client before revoking
if (clientId !== tokenIssuingClientId(provider)) {
throw new Error('client_id does not match the client that issued this token');
} Try / catch
try {
await remoteRevoke(provider, issuer, clientId, token);
} catch (e) {
if (String(e).includes('HTTP 400')) {
clearLocalToken(provider); // some providers 400 on already-revoked tokens
} else if (isRetryable(e)) {
retryWithBackoff();
} else { throw e; }
} Prevention
- Always revoke with the same client_id that obtained the token
- Treat 400 'already revoked' as success and clear local state
- Retry 5xx revocation responses with backoff; alert on persistent failures
When it happens
Trigger: POSTing the token + client_id to the provider's revoke URL and receiving 4xx/5xx — e.g. `invalid_client` (wrong client_id), `unsupported_token_type`, 401/403 auth failure at the revocation endpoint, or provider 5xx.
Common situations: client_id not matching the one that issued the token (revocation endpoints often require the original client); token already revoked (some providers return 400); provider outage; auth misconfiguration for confidential clients.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- has no remote revoke endpoint
- MCP server rejected the request with and refreshing the…
- OAuth failed ( )
- OAuth returned HTTP that was not token JSON
- OIDC discovery failed with HTTP
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/558c5a3bdd0a9acb.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/oauth.rs:1046
parse_oauth_form_response(status, &body, "refresh", params)
}
/// Best-effort remote revoke through the seam. Callers clear local
/// credentials regardless of this outcome.
pub(crate) fn revoke_remote_token_via(
client: &dyn OAuthFormClient,
params: &OAuthProviderParams,
issuer: &str,
client_id: &str,
token: &str,
) -> Result<()> {
let Some(revoke_url) = remote_revoke_url(params, issuer) else {
bail!("{} has no remote revoke endpoint", params.display_name);
};
let (status, body) =
client.post_form(&revoke_url, &[("token", token), ("client_id", client_id)])?;
if !(200..300).contains(&status) {
bail!(
"{} OAuth revoke failed with HTTP {status}: {}",
params.display_name,
compact_form_error(&body)
);
}
Ok(())
}
// ── PKCE browser login ────────────────────────────────────────────────
/// RFC 7636 S256 PKCE pair. Custom Debug: the verifier is exchanged for
/// bearer material and never prints.
#[derive(Clone)]
pub struct PkceChallenge {
pub verifier: String,
pub challenge: String,
}
View on GitHub (pinned to 73e0f67d83)