decolua/9router · error · Error

Zed models failed: ${response.status} ${text}

Error message

Zed models failed: ${response.status} ${text}

What it means

resolveZedModels calls Zed's model-surfacing endpoint (with client headers like client_supports_xai) and, if the HTTP response is not ok, throws "Zed models failed: <status> <body text>". The status and truncated body are embedded to expose the upstream reason (401 auth, 403 org access, 5xx outage).

Source

Thrown at open-sse/shared/zedAuth.js:379

  if (!options.forceRefresh && cached && cached.expiresAt > Date.now()) return cached;

  const existing = modelInflight.get(key);
  if (existing && !options.forceRefresh) return existing;

  const promise = (async () => {
    const response = await zedLlmFetch(credentials, "/models", {
      ...options,
      fetchOptions: {
        method: "GET",
        headers: {
          Accept: "application/json",
          [ZED_HEADERS.clientSupportsXai]: "true",
        },
      },
    });
    if (!response.ok) {
      const text = await response.text().catch(() => "");
      throw new Error(`Zed models failed: ${response.status} ${text}`);
    }
    const data = await response.json();
    const rawModels = Array.isArray(data?.models) ? data.models : [];
    const models = rawModels
      .map(mapZedModel)
      .filter(Boolean)
      .filter((model) => !model.isDisabled);
    const rawById = new Map();
    for (const raw of rawModels) {
      const id = normalizeZedModelId(raw?.id);
      if (id) rawById.set(id, raw);
    }
    const entry = {
      expiresAt: Date.now() + MODEL_CACHE_TTL_MS,
      models,
      rawModels,
      rawById,
      defaultModel: normalizeZedModelId(data?.default_model ?? data?.defaultModel),

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read the embedded status/body: 401/403 → refresh the Zed LLM token (forceRefresh) or re-run sign-in.
  2. Retry after token refresh; if 5xx, wait for Zed cloud recovery and add retry/backoff around the call.
  3. Verify the credential still has valid userId+accessToken (see buildZedUserAuthHeader) before calling.
  4. Check network/proxy path — a proxy 403/502 will surface here as the upstream status.

Example fix

// before
const models = await resolveZedModels(credentials); // throws on 401
// after
if (shouldRefreshZedLlmToken(response)) await fetchZedLlmToken(credentials, { forceRefresh: true });
const models = await resolveZedModels(credentials);
Defensive patterns

Strategy: retry

Validate before calling

// ensure a fresh LLM token before resolving models:
await fetchZedLlmToken(credentials, { forceRefresh: true }); // refresh when shouldRefreshZedLlmToken(lastResponse) is true

Type guard

const resOk = (r) => typeof r?.ok === "boolean" ? r.ok : false;

Try / catch

try {
  const models = await resolveZedModels(credentials);
} catch (e) {
  if (String(e.message).startsWith("Zed models failed:")) {
    const m = e.message.match(/failed: (\d+)/);
    if (m && [401, 403].includes(+m[1])) {
      await fetchZedLlmToken(credentials, { forceRefresh: true });
      return resolveZedModels(credentials); // retry once with fresh token
    }
    if (m && +m[1] >= 500) return cachedModels; // serve stale catalog
  }
  throw e;
}

Prevention

When it happens

Trigger: The Zed models catalog fetch returns a non-2xx status — most commonly 401/403 because the user auth header (userId + LLM token) is expired or invalid, or 5xx during a Zed cloud incident.

Common situations: LLM token expired (Zed tokens are short-lived and the refresh path failed); org switched or revoked; corporate proxy returning 403/502; calling models before fetchZedLlmToken ever succeeded.

Related errors


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