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

  1. 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
  2. Re-initiate the Codex OAuth connect flow to get a fresh authorize URL and retry
  3. Verify the redirect URI registered for the provider matches the proxy on 127.0.0.1:1455
  4. Check provider status if the message indicates a server-side error, then retry later
  5. 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

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


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/1b9117927506c25b. Report an issue: GitHub.