decolua/9router · warning · Error
desc ? `Windsurf auth failed: ${err} (${desc})` : `Windsurf
Error message
desc ? `Windsurf auth failed: ${err} (${desc})` : `Windsurf auth failed: ${err}` What it means
parseWindsurfCallback inspects the OAuth callback query string and throws this when the provider redirected back with error/error_description parameters instead of a token. The message carries both the OAuth error code and the human-readable description. It means Windsurf's signin refused the login before any token was issued.
Source
Thrown at src/lib/oauth/providers/windsurf.js:38
if (!res.ok) throw new Error(`Windsurf ${path} HTTP ${res.status}: ${text.slice(0, 200)}`);
try { return JSON.parse(text); } catch { throw new Error(`Windsurf ${path} invalid JSON`); }
}
// Parse Windsurf callback (query string or full URL): ?access_token=...&state=...
function parseWindsurfCallback(raw, expectedState) {
const text = String(raw || "").trim();
let queryStr = text;
if (text.includes("?")) queryStr = text.slice(text.indexOf("?") + 1);
if (text.startsWith("#")) queryStr = text.slice(1);
const params = Object.fromEntries(new URLSearchParams(queryStr));
const pick = (keys) => {
for (const k of keys) { const v = params[k]; if (v && String(v).trim()) return String(v).trim(); }
return null;
};
const err = pick(["error"]);
if (err) {
const desc = pick(["error_description"]);
throw new Error(desc ? `Windsurf auth failed: ${err} (${desc})` : `Windsurf auth failed: ${err}`);
}
const accessToken = pick(["access_token", "token"]);
if (!accessToken) throw new Error("Windsurf callback missing access_token");
const state = pick(["state"]);
if (expectedState && state && state !== expectedState) {
throw new Error("Windsurf callback state mismatch");
}
return { firebaseIdToken: accessToken };
}
// POST RegisterUser {firebase_id_token} → {apiKey, apiServerUrl, name}
async function fetchWindsurfRegisterUser(firebaseIdToken) {
const data = await windsurfSeatRequest(WINDSURF_CONFIG.registerApiBaseUrl, WINDSURF_CONFIG.registerPath, {
firebase_id_token: firebaseIdToken,
});
const apiKey = extractJsonPath(data, [["apiKey"], ["api_key"]]);
if (!apiKey) throw new Error("Windsurf RegisterUser missing apiKey");
const apiServerUrl = extractJsonPath(data, [["apiServerUrl"], ["api_server_url"]]) || WINDSURF_CONFIG.defaultApiServerUrl;View on GitHub (pinned to 90b52e06ff)
Solutions
- Read err and desc from the message — they state exactly why Windsurf refused (e.g. access_denied)
- Ask the user to retry the sign-in and complete the Windsurf login/consent screen
- Verify client_id and redirect_uri in WINDSURF_CONFIG match the registered Windsurf app
- Check the Windsurf account actually has an active seat/subscription
- Clear browser cookies for windsurf.com if a stale session causes the error
Example fix
// before
const { firebaseIdToken } = parseWindsurfCallback(callbackUrl, state);
// after
let fb;
try { ({ firebaseIdToken: fb } = parseWindsurfCallback(callbackUrl, state)); }
catch (e) {
if (e.message.startsWith('Windsurf auth failed')) throw new Error('Sign-in was rejected by Windsurf: ' + e.message + ' — please retry and complete the login');
throw e;
} Defensive patterns
Strategy: validation
Validate before calling
// inspect the callback BEFORE parsing so you can show a friendly message
const params = new URLSearchParams(raw.slice(raw.indexOf('?') + 1));
if (params.get('error')) {
throw new Error(`Sign-in rejected by Windsurf: ${params.get('error')} — ${params.get('error_description') || 'retry and complete login'}`);
} Type guard
const isAuthRejection = (raw) => /([?&#])error=/.test(String(raw));
Try / catch
try { const { firebaseIdToken } = parseWindsurfCallback(raw, state); }
catch (e) {
if (e.message.startsWith('Windsurf auth failed')) {
return promptReconnect('Windsurf sign-in was not completed: ' + e.message);
}
throw e;
} Prevention
- Always complete the Windsurf consent screen; cancelling produces ?error= redirects
- Keep client_id/redirect_uri in WINDSURF_CONFIG matching the registered app
- Never retry automatically on error callbacks — require user re-authentication
- Surface error_description to the user verbatim; it names the exact cause
When it happens
Trigger: User cancels the Windsurf signin page; login fails server-side (access_denied); the firebase auth step inside windsurf.com errors and the redirect carries ?error=...; a malformed auth URL makes the provider respond with an error redirect.
Common situations: User closes/aborts the consent screen; Windsurf account has no valid subscription/seat; misconfigured client_id makes Windsurf reject the app; stale cached signin session.
Related errors
- `Windsurf ${path} HTTP ${res.status}: ${text.slice(0, 200)}`
- `Windsurf ${path} invalid JSON`
- Windsurf callback missing access_token
- Windsurf callback state mismatch
- Windsurf RegisterUser missing apiKey
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/3a86dcdadd6e9b81.
Report an issue: GitHub.