decolua/9router · warning · Error

provider === "xai" ? "Paste the callback URL or copied xAI c

Error message

provider === "xai" ? "Paste the callback URL or copied xAI code" : provider === "kimchi" ? "No Kimchi token found in URL" : "No authorization code found in URL"

What it means

OAuthModal.handleManualSubmit parses the callback URL the user pasted into the manual-input box of the OAuth connect modal. After parsing, if the URL contains neither a `code` nor a `token` query parameter, it throws a provider-specific message telling the user the pasted input had no authorization code. This is a client-side validation error shown in the modal's error step, not a server failure.

Source

Thrown at src/shared/components/OAuthModal.js:639

      }

      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");
    }
  };

  // Clear session on modal close + cleanup proxy
  const handleClose = useCallback(() => {
    if (provider === "codex") {

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Re-run the OAuth flow and copy the full callback URL exactly as it appeared in the address bar, including `?code=...`
  2. For xai, paste just the copied xAI code (no `://`, no `?`) so completeXaiManualCode handles it, or a URL containing `code=`
  3. For kimchi, paste the bare token or a URL containing `?token=...`
  4. If the token is a JWT, paste the raw `eyJ...` string so the JWT fast-path (line 613) runs
  5. Check the URL wasn't truncated — hash-based tokens (#access_token) are not visible to this parser; paste the token value directly instead

Example fix

// before — pasted URL without the code param
const input = "http://localhost:56121/callback";
// throws: No authorization code found in URL

// after — full callback URL with code intact
const input = "http://localhost:56121/callback?code=abc123&state=xyz";
Defensive patterns

Strategy: validation

Validate before calling

function hasOauthPayload(input) {
  try {
    const u = new URL(input);
    return Boolean(u.searchParams.get("code") || u.searchParams.get("token"));
  } catch {
    return /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\./.test(input) || /^[^:/?]+$/.test(input);
  }
}
if (!hasOauthPayload(input)) showError("Paste the full callback URL containing ?code=...");

Type guard

function isCallbackUrlWithCode(v) {
  return typeof v === "string" && v.includes("://") && new URLSearchParams(v.split("?")[1] || "").has("code");
}

Try / catch

try {
  await handleManualSubmit();
} catch (e) {
  if (/authorization code|Kimchi token|xAI code/.test(e.message)) {
    setStep("manual"); // re-prompt for input instead of dead-ending
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling handleManualSubmit (submitting the manual input in the OAuth modal) when `callbackUrl` parses to a valid URL but `url.searchParams.get('code')` and `get('token')` are both null — e.g. pasting the provider console's origin URL, the post-logout redirect page, or a callback URL whose query was stripped.

Common situations: User pastes the callback URL after the browser already consumed/removed the `code` param; copies the wrong URL (login page instead of callback); pastes a base URL with `?` but no `code=`; for xai pastes a full URL instead of just the copied code so the raw-code branch at line 618 is skipped; trailing-fragment URLs like `#access_token=...` where the token lives in the hash, not searchParams.

Related errors


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