decolua/9router · error · Error

`Windsurf ${path} HTTP ${res.status}: ${text.slice(0, 200)}`

Error message

`Windsurf ${path} HTTP ${res.status}: ${text.slice(0, 200)}`

What it means

windsurfSeatRequest POSTs JSON to a Windsurf endpoint and throws this when the HTTP response status is not 2xx. The message embeds the endpoint path, status code, and the first 200 chars of the response body so you can see the upstream rejection reason. It is a fail-fast guard: error bodies may not be JSON, so the raw text is surfaced instead of letting JSON.parse mask it.

Source

Thrown at src/lib/oauth/providers/windsurf.js:20

import { extractJsonPath } from "./_shared.js";

// ───────────────────────────────────────────────────────────────────────────
// Windsurf OAuth helpers
// ───────────────────────────────────────────────────────────────────────────

async function windsurfSeatRequest(baseUrl, path, body) {
  const url = `${baseUrl.replace(/\/$/, "")}${path}`;
  const res = await fetch(url, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      "User-Agent": WINDSURF_CONFIG.userAgent,
    },
    body: JSON.stringify(body),
  });
  const text = await res.text();
  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}`);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read the status and body slice in the message — 401/403 means the firebase_id_token is invalid or expired; re-run the OAuth flow to get a fresh one
  2. Verify WINDSURF_CONFIG registerApiBaseUrl / apiServerUrl in src/lib/oauth/constants/oauth.js match Windsurf's current API host
  3. Retry after a delay if status is 429 or 5xx (upstream throttle/outage)
  4. Check network/proxy settings (HTTPS_PROXY) that could inject non-Windsurf error pages
  5. Run the Windsurf OAuth flow again end-to-end rather than reusing an old pasted token

Example fix

// before: caller lets the throw propagate and the whole OAuth flow fails
const reg = await fetchWindsurfRegisterUser(firebaseIdToken);
// after: surface a clear, actionable message to the dashboard user
let reg;
try { reg = await fetchWindsurfRegisterUser(firebaseIdToken); }
catch (e) {
  if (/HTTP 40[13]/.test(e.message)) throw new Error('Windsurf token expired — reconnect the account');
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: ensure a JWT-shaped firebase id token before hitting Windsurf
const jwtOk = (t) => typeof t === 'string' && t.trim().split('.').length === 3;
if (!jwtOk(firebaseIdToken)) throw new Error('Refusing call: missing/malformed firebase_id_token');

Type guard

const isWindsurfHttpError = (e) => e instanceof Error && /^Windsurf \S+ HTTP \d{3}/.test(e.message);
const statusOf = (e) => { const m = e.message.match(/HTTP (\d{3})/); return m ? Number(m[1]) : null; };

Try / catch

try {
  data = await windsurfSeatRequest(baseUrl, path, body);
} catch (e) {
  const s = isWindsurfHttpError(e) ? statusOf(e) : null;
  if (s === 429 || (s && s >= 500)) { await sleep(2000); data = await windsurfSeatRequest(baseUrl, path, body); }
  else if (s === 401 || s === 403) { throw new Error('Windsurf credential rejected — re-run OAuth'); }
  else throw e;
}

Prevention

When it happens

Trigger: Any windsurfSeatRequest call (RegisterUser, GetOneTimeAuthToken, GetCurrentUser) where Windsurf/Codeium servers return 401/403/404/429/5xx — e.g. expired or invalid firebase_id_token, wrong registerApiBaseUrl/apiServerUrl, or upstream outage.

Common situations: Users pasting an already-expired Firebase JWT; Windsurf changing their API host or paths; rate limiting after repeated seat checks; corporate proxy intercepting with a 403/502 page.

Related errors


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