{"record":{"id":"2734d66ae7fd935e","repo":"decolua/9router","slug":"zed-models-failed-response-status-text","errorCode":null,"errorMessage":"Zed models failed: ${response.status} ${text}","messagePattern":"Zed models failed: (.+?) (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"open-sse/shared/zedAuth.js","lineNumber":379,"sourceCode":"  if (!options.forceRefresh && cached && cached.expiresAt > Date.now()) return cached;\n\n  const existing = modelInflight.get(key);\n  if (existing && !options.forceRefresh) return existing;\n\n  const promise = (async () => {\n    const response = await zedLlmFetch(credentials, \"/models\", {\n      ...options,\n      fetchOptions: {\n        method: \"GET\",\n        headers: {\n          Accept: \"application/json\",\n          [ZED_HEADERS.clientSupportsXai]: \"true\",\n        },\n      },\n    });\n    if (!response.ok) {\n      const text = await response.text().catch(() => \"\");\n      throw new Error(`Zed models failed: ${response.status} ${text}`);\n    }\n    const data = await response.json();\n    const rawModels = Array.isArray(data?.models) ? data.models : [];\n    const models = rawModels\n      .map(mapZedModel)\n      .filter(Boolean)\n      .filter((model) => !model.isDisabled);\n    const rawById = new Map();\n    for (const raw of rawModels) {\n      const id = normalizeZedModelId(raw?.id);\n      if (id) rawById.set(id, raw);\n    }\n    const entry = {\n      expiresAt: Date.now() + MODEL_CACHE_TTL_MS,\n      models,\n      rawModels,\n      rawById,\n      defaultModel: normalizeZedModelId(data?.default_model ?? data?.defaultModel),","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/shared/zedAuth.js#L361-L397","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the embedded status/body: 401/403 → refresh the Zed LLM token (forceRefresh) or re-run sign-in.","Retry after token refresh; if 5xx, wait for Zed cloud recovery and add retry/backoff around the call.","Verify the credential still has valid userId+accessToken (see buildZedUserAuthHeader) before calling.","Check network/proxy path — a proxy 403/502 will surface here as the upstream status."],"exampleFix":"// before\nconst models = await resolveZedModels(credentials); // throws on 401\n// after\nif (shouldRefreshZedLlmToken(response)) await fetchZedLlmToken(credentials, { forceRefresh: true });\nconst models = await resolveZedModels(credentials);","handlingStrategy":"retry","validationCode":"// ensure a fresh LLM token before resolving models:\nawait fetchZedLlmToken(credentials, { forceRefresh: true }); // refresh when shouldRefreshZedLlmToken(lastResponse) is true\n","typeGuard":"const resOk = (r) => typeof r?.ok === \"boolean\" ? r.ok : false;","tryCatchPattern":"try {\n  const models = await resolveZedModels(credentials);\n} catch (e) {\n  if (String(e.message).startsWith(\"Zed models failed:\")) {\n    const m = e.message.match(/failed: (\\d+)/);\n    if (m && [401, 403].includes(+m[1])) {\n      await fetchZedLlmToken(credentials, { forceRefresh: true });\n      return resolveZedModels(credentials); // retry once with fresh token\n    }\n    if (m && +m[1] >= 500) return cachedModels; // serve stale catalog\n  }\n  throw e;\n}","preventionTips":["Refresh the LLM token proactively (shouldRefreshZedLlmToken) before catalog calls.","Cache the last good model list and fall back to it on 5xx.","Add exponential backoff for transient statuses (429/5xx)."],"tags":["zed","http-error","auth","model-catalog"],"backgroundTag":"http-401-unauthorized","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}