decolua/9router · error
${callbackParams.error_description || callbackParams.error}
Error message
${callbackParams.error_description || callbackParams.error} What it means
The xAI OAuth provider returned an authorization error to the local loopback callback (e.g. ?error=access_denied&error_description=...). connect() surfaces the provider's error_description, or the bare error code if no description was sent, instead of proceeding to the token exchange. This is the OAuth spec-defined failure path of the authorization-code flow, thrown before any tokens are requested.
Source
Thrown at src/lib/oauth/services/xai.js:217
console.log("\nOpening browser for xAI authentication...");
console.log(`If browser doesn't open, visit:\n${authUrl}\n`);
await open(authUrl);
spinner.start("Waiting for xAI authorization...");
await new Promise((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error("Authentication timeout (5 minutes)")), 300000);
const iv = setInterval(() => {
if (callbackParams) {
clearInterval(iv);
clearTimeout(timeout);
resolve();
}
}, 100);
});
close();
if (callbackParams.error) {
throw new Error(callbackParams.error_description || callbackParams.error);
}
if (!callbackParams.code) throw new Error("No authorization code received");
if (callbackParams.state !== state) throw new Error("Invalid state parameter");
spinner.start("Exchanging code for tokens...");
const tokens = await this.exchangeXaiCode({
tokenUrl,
code: callbackParams.code,
redirectUri,
codeVerifier,
});
const email = decodeIdTokenEmail(tokens.id_token);
spinner.succeed("xAI connected successfully!");
return { tokens, email };
} catch (error) {
spinner.fail(`Failed: ${error.message}`);
throw error;View on GitHub (pinned to 90b52e06ff)
Solutions
- Read the thrown message (it is xAI's error_description) and address the specific cause: access_denied means the user must re-run connect() and approve the consent prompt
- Re-run connect() and complete authorization in the browser window instead of cancelling
- Verify XAI_CONFIG.clientId/redirect settings and that discoverEndpoints() resolves valid xAI authorize/token URLs
- Check the xAI account/organization has the necessary entitlements for the requested scopes
- Retry later if the message indicates a server-side xAI issue (server_error, temporarily_unavailable)
Example fix
// before: denial surfaces only as a raw CLI failure
await xai.connect();
// after: handle the user-denied case explicitly
try {
await xai.connect();
} catch (e) {
if (/access_denied/i.test(e.message)) {
console.log('Authorization was cancelled — rerun connect and approve access.');
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot pre-validate the provider's decision; inspect the callback before or catch the throw.
const params = new URL(callbackUrl).searchParams;
if (params.get('error')) {
console.log('OAuth provider error:', params.get('error_description') || params.get('error'));
} Type guard
function isOAuthError(params) {
return typeof params === 'object' && params !== null && typeof params.error === 'string' && params.error.length > 0;
} Try / catch
try {
await xai.connect();
} catch (err) {
// message is error_description || error from the provider
if (err.message.includes('access_denied')) {
// user cancelled — prompt retry
} else {
throw err;
}
} Prevention
- Complete the consent screen rather than cancelling it
- Verify xAI client_id/redirect config before starting the flow
- Keep the auth URL unmodified and use the freshly generated one
- Check account entitlements for requested scopes
- Retry on transient server_error codes
When it happens
Trigger: During xaiOAuthService.connect(), the browser redirect lands on the loopback callback with a non-empty `error` query parameter (e.g. access_denied, unauthorized_client, server_error) because xAI's authorize endpoint rejected the request.
Common situations: User clicked 'Cancel'/'Deny' on the xAI consent screen; the xAI account lacks access to the requested scopes; the authorize URL carries a bad client_id or redirect_uri (misconfigured/reordered XAI_CONFIG or stale discovered endpoints); rate limits or a transient xAI outage producing server_error; cached browser session reusing an expired/revoked consent.
Related errors
- No authorization code received
- Invalid state parameter
- xAI OAuth session not found; restart the login flow and past
- Missing xAI authorization code
- xai discovery ${field} is empty
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/6786ec889868b181.
Report an issue: GitHub.