decolua/9router · error · Error
Zed did not return an LLM token
Error message
Zed did not return an LLM token
What it means
fetchZedLlmToken POSTs to Zed's LLM-token endpoint with the organization id and extracts the token from the response, accepting `token` as a string, or as an object/array with `token[0]` or `token.value`. If none of these shapes yield a non-empty token it throws "Zed did not return an LLM token".
Source
Thrown at open-sse/shared/zedAuth.js:286
"Content-Type": "application/json",
Accept: "application/json",
Authorization: buildZedUserAuthHeader(credentials),
};
const systemId = getSystemId(credentials);
if (systemId) headers[ZED_HEADERS.systemId] = systemId;
const data = await fetchJson(
zedUrl(config, "cloudBaseUrl", "/client/llm_tokens", ZED_CLOUD_BASE_URL),
{
method: "POST",
headers,
body: JSON.stringify({ organization_id: organizationId }),
signal: options.signal ?? undefined,
},
);
const token =
typeof data?.token === "string" ? data.token : data?.token?.[0] || data?.token?.value;
if (!token) throw new Error("Zed did not return an LLM token");
llmTokenCache.set(cacheKey, { token, expiresAt: Date.now() + LLM_TOKEN_TTL_MS });
return token;
}
export function shouldRefreshZedLlmToken(response) {
return (
response?.status === 401 ||
!!response?.headers?.has?.(ZED_HEADERS.expiredToken) ||
!!response?.headers?.has?.(ZED_HEADERS.outdatedToken)
);
}
export async function zedLlmFetch(credentials, path, options = {}) {
const config = options.config || {};
const url = zedUrl(config, "llmBaseUrl", path, ZED_LLM_BASE_URL);
const buildRequest = async (forceRefresh) => {
const token = await fetchZedLlmToken(credentials, { ...options, forceRefresh });
return proxyAwareFetch(url, {View on GitHub (pinned to 90b52e06ff)
Solutions
- Log the raw response body and check which shape `token` actually has; if it moved to a new key, adjust the extraction.
- Confirm the selected organization has LLM/active-seat access on Zed cloud; try another organizationId.
- Re-authenticate (forceRefresh or new sign-in) — an expired session can yield an empty success response.
- Check the response isn't an HTML/error page being JSON-parsed into {raw: text}; inspect Content-Type.
Example fix
// before
const data = { token: null }; // server returned empty
if (!token) throw ...
// after — verify upstream entitlement, or extract from alternate shape:
const token = data?.token?.value || data?.token?.[0] || data?.llm_token; Defensive patterns
Strategy: fallback
Validate before calling
// can't validate pre-call; validate post-call instead:
if (res.ok) {
const data = await res.json();
const token = data?.token?.value || (Array.isArray(data?.token) ? data.token[0] : data?.token) || data?.llm_token;
if (!token) throw new Error(`Unexpected LLM token payload: ${JSON.stringify(data).slice(0, 200)}`);
}
Type guard
const hasLlmToken = (d) => typeof d?.token === "string" || (Array.isArray(d?.token) && typeof d.token[0] === "string") || typeof d?.token?.value === "string" || typeof d?.llm_token === "string";
Try / catch
try {
const token = await fetchZedLlmToken(credentials, { organizationId });
} catch (e) {
if (e.message === "Zed did not return an LLM token") {
// check org entitlement / forceRefresh / inspect raw body, then retry once
} else throw e;
} Prevention
- Confirm the organization has active LLM seats before requesting tokens.
- Log raw response bodies for the token endpoint to catch contract changes early.
- Force re-auth when a 200 response yields an empty token — it usually means a stale session.
When it happens
Trigger: The Zed LLM-token endpoint responds 200 but with an empty/malformed body — e.g. `{"token":[]}`, `{}`, or a body whose `token` field is null — typically when the org has no LLM access or the endpoint contract changed.
Common situations: Organization lacks LLM entitlement/seat; Zed API version changed the response shape (token now under a different key); proxy or captive portal returned a 200 HTML page parsed as {raw:...}.
Related errors
- loadCodeAssist failed: HTTP ${response.status} ${errorText.s
- onboardUser HTTP ${response.status}: ${errorText.slice(0, 20
- Missing Zed private key verifier; restart the login flow
- Missing Zed callback URL
- No Zed organization selected
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/7e7c08133af4500c.
Report an issue: GitHub.