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

  1. Retry the operation — transient network slowness is the most common cause
  2. Check connectivity/curl the token endpoint directly to measure latency
  3. Route around VPN/proxies that stall the request
  4. 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

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

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/621dd4d8332f763c. Report an issue: GitHub.