musistudio/claude-code-router · error · Error
Grok CLI OAuth token refresh timed out after ${timeoutMs}ms.
Error message
Grok CLI OAuth token refresh timed out after ${timeoutMs}ms. What it means
The fetch to the Grok OAuth token endpoint was aborted by an AbortController timer before completing, and the resulting AbortError is rethrown as a descriptive timeout. It indicates the refresh HTTP request exceeded kimiOauth/grokOauth refresh timeoutMs.
Source
Thrown at packages/core/src/agents/local-providers/grok.ts:723
throw new GrokRefreshAuthError(response.status, message);
}
throw new Error(message);
}
const accessToken = readString(payload?.access_token) || readString(payload?.accessToken);
if (!accessToken) {
throw new Error("Grok CLI OAuth token refresh did not return an access token.");
}
const refreshed: GrokTokenSet = {
...auth,
accessToken,
expiresAt: refreshedGrokExpiresAt(accessToken, payload),
refreshToken: readString(payload?.refresh_token) || readString(payload?.refreshToken) || refreshToken
};
persistRefreshedGrokAuth(refreshed);
return refreshed;
} catch (error) {
if (error instanceof Error && error.name === "AbortError") {
throw new Error(`Grok CLI OAuth token refresh timed out after ${timeoutMs}ms.`);
}
throw error;
} finally {
clearTimeout(timer);
}
}
async function grokTokenEndpoint(auth: GrokTokenSet): Promise<string> {
const configured = readString(process.env.GROK_OIDC_TOKEN_ENDPOINT);
if (configured) {
return configured;
}
const issuer = (auth.oidcIssuer || readString(process.env.GROK_OIDC_ISSUER) || grokDefaultOidcIssuer).replace(/\/+$/, "");
const metadataUrl = `${issuer}/.well-known/openid-configuration`;
const timeoutMs = normalizeGrokOauthTimeout(process.env.GROK_OIDC_REFRESH_TIMEOUT_MS);
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {View on GitHub (pinned to 99f24806c6)
Solutions
- Retry the operation — transient network slowness is the most common cause
- Check connectivity/curl the token endpoint directly to measure latency
- Route around VPN/proxies that stall the request
- If it consistently times out, check for firewall rules blocking the OAuth host
Defensive patterns
Strategy: retry
Validate before calling
const start = Date.now(); const reachable = await pingEndpoint(tokenEndpoint, 2000); if (!reachable) skipRefreshForNow();
Try / catch
catch (e) {
if (e instanceof Error && e.message.includes('timed out')) {
await sleep(backoffMs(attempt++)); // retryable
}
} Prevention
- Wrap refresh in a retry loop with exponential backoff for timeout-class errors
- Pre-check network connectivity before launching OAuth flows
- Cap total retries to avoid hanging the agent startup
When it happens
Trigger: refreshGrokAuth's fetch (or response.text()) takes longer than the configured timeoutMs, controller.abort() fires, and the catch converts the AbortError into this message.
Common situations: Slow or blocked network egress, DNS black-holing, an intercepting proxy that hangs on POST bodies, or the token endpoint being temporarily unreachable during provider incidents.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Grok CLI OIDC discovery timed out after ${timeoutMs}ms.
- Kimi CLI OAuth token refresh timed out after ${kimiOauthRefr
- Grok CLI OAuth token refresh did not return an access token.
- Grok CLI OIDC discovery returned HTTP ${response.status}${to
- OpenRouter endpoints request timed out after ${endpointFetch
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/621dd4d8332f763c.
Report an issue: GitHub.