decolua/9router · error · Error
authData.error
Error message
authData.error
What it means
In startProxyFlow, after fetching `/api/oauth/{providerId}/authorize` (which builds the upstream authorize URL for the Trae/Windsurf/Zed proxy flow), the modal throws when the HTTP response status is not ok, surfacing the server-provided `error` string. This means the server-side authorize step failed before any popup was opened. The message shown to the user is whatever the API returned in its JSON body.
Source
Thrown at src/shared/components/OAuthModal.js:195
setError("Authorization timeout");
setStep("error");
setPolling(false);
}, [provider, onSuccess]);
// Trae/Windsurf proxy OAuth flow: dynamic-port local callback → auto exchange.
const startProxyFlow = useCallback(async (providerId) => {
// 1. Start the local callback server (returns a dynamic port + callback URL).
const startRes = await fetch(`/api/oauth/${providerId}/start-proxy`);
const startData = await startRes.json();
if (!startRes.ok || !startData.success || !startData.callbackUrl) {
throw new Error(startData.reason || startData.error || `Failed to start ${providerId} callback server`);
}
// 2. Build the authorize URL with redirect_uri = proxy callback URL.
const authorizeUrl = new URL(`/api/oauth/${providerId}/authorize`, window.location.origin);
authorizeUrl.searchParams.set("redirect_uri", startData.callbackUrl);
const authRes = await fetch(authorizeUrl);
const authData = await authRes.json();
if (!authRes.ok) throw new Error(authData.error);
// 3. Register the session so the proxy can match the incoming callback.
// Zed also passes code_verifier (encodes the RSA private key for decrypt);
// sent via POST body so the private key never lands in URL/query logs.
const regBody = { state: authData.state };
if (authData.codeVerifier) regBody.codeVerifier = authData.codeVerifier;
await fetch(`/api/oauth/${providerId}/register-session`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(regBody),
});
// 4. Open popup; proxy auto-exchanges on callback, modal polls poll-status.
setAuthData({ ...authData, proxyProvider: providerId });
setStep("waiting");
popupRef.current = window.open(authData.authUrl, "oauth_popup", "width=600,height=700");
if (!popupRef.current) setStep("input"); // popup blocked → fall back to manual paste
}, []);
// Start OAuth flowView on GitHub (pinned to 90b52e06ff)
Solutions
- Read the exact `error` string from the response body to identify the server-side cause
- Verify the provider's OAuth client credentials are configured in the gateway settings
- Re-run the flow; if start-proxy failed, check `startData.success`/`reason` from /start-proxy first
- Check gateway logs for the upstream request that produced the error
Example fix
// before
const authRes = await fetch(authorizeUrl);
const authData = await authRes.json();
if (!authRes.ok) throw new Error(authData.error);
// after
const authRes = await fetch(authorizeUrl);
const authData = await authRes.json();
if (!authRes.ok) throw new Error(authData.error || authData.reason || `Authorize failed (${authRes.status})`); Defensive patterns
Strategy: try-catch
Validate before calling
const r = await fetch(authorizeUrl);
if (!r.ok) console.error("authorize failed:", (await r.json()).error); Type guard
null
Try / catch
try {
const res = await fetch(authorizeUrl);
const data = await res.json();
if (!res.ok) throw new Error(data.error || `Authorize failed (${res.status})`);
} catch (e) {
setError(e.message); // show retry guidance
} Prevention
- Ensure provider OAuth credentials are configured before opening the modal
- Check gateway logs for the failing upstream authorize call
- Handle non-JSON responses defensively (res.json() can throw)
When it happens
Trigger: GET /api/oauth/{trae|windsurf|zed}/authorize?redirect_uri=... returns a non-2xx status — e.g. provider credentials missing server-side, upstream authorize-URL construction failing, or the start-proxy callback URL being invalid.
Common situations: Provider OAuth client credentials not configured in the gateway; upstream provider (Trae/Windsurf/Zed) returning an error while generating the authorize URL; misconfigured redirect_uri because start-proxy failed silently; network/proxy issues between the gateway and the upstream IdP.
Related errors
- `ClinePass token exchange failed: ${error}`
- `CodeBuddy state request failed: ${await response.text()}`
- `CodeBuddy Intl state request failed: ${await response.text(
- `Device auth initiation failed: ${error}`
- Failed to get user info: ${error}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/74ec22317c12746a.
Report an issue: GitHub.