decolua/9router · error · Error
No authorization code found in URL
Error message
No authorization code found in URL
What it means
handleManualSubmit throws this when the parsed callback URL has no `code` query parameter and no `error` param. A successful OAuth redirect must carry `?code=...` (plus `state`); without it the modal cannot proceed to POST /api/oauth/kiro/social-exchange to swap the code for tokens.
Source
Thrown at src/shared/components/KiroSocialOAuthModal.js:82
// Parse callback URL - can be either kiro:// or http://localhost format
let url;
try {
url = new URL(callbackUrl);
} catch (e) {
// If URL parsing fails, might be malformed
throw new Error("Invalid callback URL format");
}
const code = url.searchParams.get("code");
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) {
throw new Error("No authorization code found in URL");
}
// Exchange code for tokens
const res = await fetch("/api/oauth/kiro/social-exchange", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code,
codeVerifier: authData.codeVerifier,
provider,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
setStep("success");
onSuccess?.();View on GitHub (pinned to 90b52e06ff)
Solutions
- Re-do the authorization and copy the final browser URL after the provider redirects — it must contain ?code=...
- Verify you copied the full URL including query string (some browsers/apps strip it on copy).
- If the code appears after '#' instead of '?', the provider used the implicit flow — this modal requires the authorization-code flow; fix the provider/app config.
- Confirm `state` also matches what initAuth issued; a state-only URL means the redirect never completed.
Example fix
// before
if (!code) {
throw new Error("No authorization code found in URL");
}
// after
if (!code) {
const hashParams = new URLSearchParams(url.hash.replace(/^#/, ""));
throw new Error(`No authorization code found in URL (params: ${[...url.searchParams.keys(), ...hashParams.keys()].join(", ") || "none"})`);
} Defensive patterns
Strategy: validation
Validate before calling
function callbackHasCode(s) {
try {
const u = new URL(String(s).trim());
const q = u.searchParams.get("code");
const h = new URLSearchParams(u.hash.replace(/^#/, "")).get("code"); // implicit-flow fallback
return Boolean(q || h);
} catch { return false; }
}
if (!callbackHasCode(callbackUrl)) {
setError("URL must contain ?code= — re-copy the address after the provider redirects back");
return;
} Prevention
- Copy the URL only after the provider's final redirect completes.
- Ensure the full query string survives the copy (some apps strip it).
- Use the authorization-code flow; fragment (#code=...) responses aren't supported.
- Don't paste the configured redirect_uri itself — paste the actual redirected address.
When it happens
Trigger: User pastes a callback URL that parses but lacks `code` — e.g. they pasted the base callback/redirect URL itself, a URL that only has `state`, a logout or error page URL, or the provider put the code in the URL fragment (#code=...) instead of the query string.
Common situations: Copying the redirect_uri from app config instead of the actual redirected address; pasting the URL before completing the consent redirect; fragment-based responses (implicit flow) that this code-exchange flow doesn't support.
Related errors
- API key is required
- API key validation failed: ${error.message}
- Invalid callback URL format
- url.searchParams.get("error_description") || errorParam
- Missing Zed callback URL
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/0bd5f815b5514266.
Report an issue: GitHub.