musistudio/claude-code-router · error · Error
Grok CLI OIDC discovery did not return a token endpoint.
Error message
Grok CLI OIDC discovery did not return a token endpoint.
What it means
OIDC discovery for Grok succeeded at the HTTP level but the returned JSON lacked a token_endpoint (or tokenEndpoint) string, so no OAuth token URL could be derived. The library throws instead of guessing an endpoint.
Source
Thrown at packages/core/src/agents/local-providers/grok.ts:753
}
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 {
const response = await fetchWithSystemProxy(metadataUrl, {
headers: { accept: "application/json" },
signal: controller.signal
});
const text = await response.text();
const payload = parseJsonRecord(text);
if (!response.ok) {
throw new Error(`Grok CLI OIDC discovery returned HTTP ${response.status}${tokenRefreshErrorMessage(payload, text)}`);
}
const tokenEndpoint = readString(payload?.token_endpoint) || readString(payload?.tokenEndpoint);
if (!tokenEndpoint) {
throw new Error("Grok CLI OIDC discovery did not return a token endpoint.");
}
return tokenEndpoint;
} catch (error) {
if (error instanceof Error && error.name === "AbortError") {
throw new Error(`Grok CLI OIDC discovery timed out after ${timeoutMs}ms.`);
}
throw error;
} finally {
clearTimeout(timer);
}
}
function grokCredentialFiles(): string[] {
const explicitFile = process.env.GROK_AUTH_FILE?.trim();
return uniqueStrings([
explicitFile,
path.join(grokStorageRoot(), "auth.json"),
path.join(grokStorageRoot(), "credentials.json")View on GitHub (pinned to 99f24806c6)
Solutions
- Fetch the discovery URL manually and inspect the JSON for token_endpoint
- Re-run login to regenerate the cached discovery URL
- Verify the issuer matches the actual OIDC provider host
- Report if the provider changed the discovery schema
Defensive patterns
Strategy: validation
Validate before calling
const doc = await fetch(discoveryUrl).then(r => r.json());
if (typeof doc.token_endpoint !== 'string' || !doc.token_endpoint) {
throw new Error('discovery document lacks token_endpoint — refresh login config');
} Try / catch
catch (e) {
if (e instanceof Error && e.message.includes('did not return a token endpoint')) {
await relogin(); // cached discovery URL is wrong
}
} Prevention
- Validate discovery documents once and cache the validated token endpoint
- Fail fast on schema drift instead of falling back to guessed endpoints
When it happens
Trigger: The discovery document JSON parses but has no token_endpoint/tokenEndpoint field — a truncated body, a non-standard discovery document, or the URL pointing at a JSON resource that is not an OIDC configuration.
Common situations: Discovery URL points at the wrong well-known path; provider ships a partial/preview document; a proxy rewrites the response body.
Related errors
- Grok CLI OIDC discovery returned HTTP ${response.status}${to
- Grok CLI OIDC discovery timed out after ${timeoutMs}ms.
- Grok CLI OAuth token refresh did not return an access token.
- Grok CLI OAuth token refresh timed out after ${timeoutMs}ms.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/8eaba03cf152a14a.
Report an issue: GitHub.