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

  1. Read the error_description in the URL/exception for the exact provider-side cause
  2. Redo the flow and click Allow/Authorize on the consent screen
  3. If access_denied persists, check org/provider policy for third-party app access
  4. 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

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


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