decolua/9router · error · Error
url.searchParams.get("error_description") || errorParam
Error message
url.searchParams.get("error_description") || errorParam What it means
When parsing the manually pasted callback URL, if the URL contains an `error` query parameter the modal throws with the `error_description` (or the bare error code). This is the upstream OAuth provider redirecting back with an authorization error (RFC 6749 §4.1.2.1) instead of a code, and the modal surfaces it verbatim.
Source
Thrown at src/shared/components/OAuthModal.js:635
if (provider === "xai" && input && !input.includes("://") && !input.includes("?") && !input.includes("code=")) {
await completeXaiManualCode(input);
return;
}
if (provider === "kimchi" && input && !input.includes("://") && !input.includes("?")) {
await exchangeTokens(input, null);
return;
}
const url = new URL(input);
const code = url.searchParams.get("code");
const token = url.searchParams.get("token");
const state = url.searchParams.get("state");
const errorParam = url.searchParams.get("error");
if (errorParam) {
throw new Error(url.searchParams.get("error_description") || errorParam);
}
if (!code && !token) {
throw new Error(
provider === "xai"
? "Paste the callback URL or copied xAI code"
: provider === "kimchi"
? "No Kimchi token found in URL"
: "No authorization code found in URL"
);
}
await exchangeTokens(token || code, state);
} catch (err) {
setError(err.message);
setStep("error");
}
};View on GitHub (pinned to 90b52e06ff)
Solutions
- Read the error_description in the URL/exception for the exact provider-side cause
- Redo the flow and click Allow/Authorize on the consent screen
- If access_denied persists, check org/provider policy for third-party app access
- If the cause is invalid_scope or redirect_uri mismatch, fix the provider app configuration in gateway settings
Example fix
// before
if (errorParam) {
throw new Error(url.searchParams.get("error_description") || errorParam);
}
// after
if (errorParam) {
throw new Error(`OAuth provider error (${errorParam}): ${url.searchParams.get("error_description") || "no description"}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
const u = new URL(callbackUrl.trim());
if (u.searchParams.get('error')) {
setError(`Provider said: ${u.searchParams.get('error_description') || u.searchParams.get('error')}`);
return;
} Type guard
const isOAuthErrorUrl = (input) => {
try { return !!new URL(input).searchParams.get('error'); } catch { return false; }
}; Try / catch
try {
await handleManualSubmit();
} catch (e) {
if (e.message.includes('access_denied')) { /* advise: click Allow on consent screen */ }
else { /* show error_description to user */ }
} Prevention
- Always click Allow/Authorize on the provider consent screen
- Check provider app configuration if errors repeat (redirect_uri, scopes)
- Inspect the callback URL's error/error_description params before submitting
- Verify account/org permissions for third-party app access
When it happens
Trigger: Pasting a callback URL like http://localhost:PORT/callback?error=access_denied&error_description=... — the user denied consent at the provider, or the provider rejected the request (invalid_scope, redirect_uri mismatch, client deleted).
Common situations: Clicking 'Cancel'/'Deny' on the provider consent screen; account lacks required scopes; provider app misconfigured (redirect_uri/client mismatch); org policies blocking third-party app access.
Related errors
- url.searchParams.get("error_description") || errorParam
- data.errorDescription || data.error
- Kiro tool input must be a JSON object
- Vertex OAuth/ADC requires a project_id. Add quota_project_id
- Vertex: failed to mint access token from Service Account JSO
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/3c21653c2c05fbfd.
Report an issue: GitHub.