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 flow

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read the exact `error` string from the response body to identify the server-side cause
  2. Verify the provider's OAuth client credentials are configured in the gateway settings
  3. Re-run the flow; if start-proxy failed, check `startData.success`/`reason` from /start-proxy first
  4. 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

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


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