decolua/9router · error · Error
url.searchParams.get("error_description") || errorParam
Error message
url.searchParams.get("error_description") || errorParam What it means
In the Codex OAuth callback proxy (Mode A, where a pending exchange session is registered for the state), the provider redirected to /callback with an `error` query parameter. The handler throws the provider's error_description (or the raw error code) so it can be recorded on the session and rendered as a failure page. This is the spec-defined authorization-failure path of the code flow.
Source
Thrown at src/lib/oauth/utils/server.js:219
const server = http.createServer(async (req, res) => {
const url = new URL(req.url, "http://localhost");
if (url.pathname !== "/callback" && url.pathname !== "/auth/callback") {
res.writeHead(404);
res.end("Not found");
return;
}
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
const errorParam = url.searchParams.get("error");
const session = state ? pendingExchanges.get(state) : null;
// Mode A: server-side exchange (session registered)
if (session) {
try {
if (errorParam) {
throw new Error(url.searchParams.get("error_description") || errorParam);
}
if (!code) throw new Error("No authorization code received");
// Lazy import to avoid circular deps
const { exchangeTokens } = await import("../providers.js");
const { createProviderConnection } = await import("@/models");
const tokenData = await exchangeTokens(
"codex",
code,
session.redirectUri,
session.codeVerifier,
state
);
const connection = await createProviderConnection({
provider: "codex",
authType: "oauth",
...tokenData,View on GitHub (pinned to 90b52e06ff)
Solutions
- Read the session.error (shown on the rendered failure page) and address the specific provider error — access_denied means re-run the flow and approve
- Re-initiate the Codex OAuth connect flow to get a fresh authorize URL and retry
- Verify the redirect URI registered for the provider matches the proxy on 127.0.0.1:1455
- Check provider status if the message indicates a server-side error, then retry later
- Ensure the state passed to register the pending session is the same one used in the authorize URL
Example fix
// before: raw thrown message only
if (errorParam) {
throw new Error(url.searchParams.get("error_description") || errorParam);
}
// after (caller side): map denial to a friendly message
try {
await codexOAuthFlow();
} catch (e) {
if (e.message === 'access_denied') {
show('Authorization denied — please approve access to continue.');
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Inspect the callback before/at the proxy.
const params = new URL(req.url, 'http://localhost').searchParams;
if (params.get('error')) {
const msg = params.get('error_description') || params.get('error');
markSessionFailed(params.get('state'), msg);
} Type guard
function hasOAuthError(searchParams) {
return searchParams instanceof URLSearchParams && searchParams.get('error') !== null;
} Try / catch
const status = getCodexSessionStatus(state);
if (status && status.status === 'error') {
if (/access_denied/.test(status.error || '')) {
// user denied consent — prompt a retry
} else {
throw new Error(status.error);
}
} Prevention
- Approve the consent screen instead of denying
- Confirm the registered redirect URI matches the 1455 proxy callback
- Register the pending exchange session with the same state used in the authorize URL
- Retry on provider-side server_error after checking provider status
- Test the flow end-to-end after any provider/client config change
When it happens
Trigger: startCodexProxy's HTTP handler receives /callback or /auth/callback with a `state` matching a pendingExchanges session and `error` present in the query string (e.g. access_denied, invalid_request).
Common situations: User denied consent on the Codex/ChatGPT authorization page; the authorize request was malformed (bad client_id, mismatched redirect_uri on port 1455); session/provider config changed between authorize and callback; upstream OpenAI-side outage yielding server_error; the browser aborted the flow mid-way and the provider reported it back.
Related errors
- No authorization code received
- Kiro tool input must be a JSON object
- No Codex access token available. Please re-authorize the con
- Missing accessToken
- Failed to save tokens
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/1b9117927506c25b.
Report an issue: GitHub.