janhq/jan · error
Failed to fetch models from
Error message
Failed to fetch models from ${provider.provider}: ${lastStatus} ${lastStatusText} What it means
fetchTopRemoteModels iterates remote provider catalog endpoints; if every attempted endpoint returns a non-OK HTTP status, it throws with the last response's status code and status text. It signals that the provider's model catalog API was reachable but rejected the request.
Solutions
- Check the provider API key in provider settings and re-authenticate
- Verify the provider base_url points at the correct API host
- Call the provider's /models endpoint with curl to confirm access
- Check network/proxy configuration that could alter responses
Example fix
// before
throw new Error(`Failed to fetch models from ${provider.provider}: ${lastStatus} ${lastStatusText}`)
// after
// inspect lastStatus first; e.g. 401 => refresh the API key before retrying
if (lastStatus === 401) throw new Error(`Invalid API key for ${provider.provider}`)
throw new Error(`Failed to fetch models from ${provider.provider}: ${lastStatus} ${lastStatusText}`) Defensive patterns
Strategy: retry
Validate before calling
const res = await fetch(url, { headers })
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`) Type guard
function isOk(r: Response): boolean { return r.ok } Try / catch
try { const models = await fetchTopRemoteModels() } catch (e) { if (String(e).includes('401')) refreshToken(); else showCatalogError(e) } Prevention
- Store and refresh provider API keys proactively
- Test provider endpoints with curl before wiring them in
- Surface HTTP status to the user instead of failing silently
When it happens
Trigger: fetchTopRemoteModels called when a provider endpoint (e.g. OpenAI, Groq) returns 401/403/404/5xx on its /models route for all attempted URLs.
Common situations: Expired or missing API key on the remote provider, wrong base_url in provider settings, provider blocking the /models endpoint, or a proxy/firewall returning an error page.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- API request failed with status
- Failed to fetch releases
- Failed to fetch HuggingFace repository
- Failed to fetch model catalog
- Failed to fetch repository files
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/8202175c729cf704.
Report an issue: GitHub.
Appendix: source
Thrown at web-app/src/lib/remoteModelCatalog.ts:231
for (let i = 0; i < attempts.length; i++) {
const result = await getJson(
fetchImpl,
`${provider.base_url}/models`,
buildHeaders(provider, attempts[i])
)
lastStatus = result.status
lastStatusText = result.statusText
if (!result.ok) {
if ([401, 403, 429].includes(result.status) && i < attempts.length - 1) continue
throw new Error(`Failed to fetch models from ${provider.provider}: ${result.status} ${result.statusText}`)
}
const body = result.body as { data?: unknown }
const rows = Array.isArray(body?.data) ? (body.data as unknown[]) : []
return normalizeCatalog(kind, rows)
}
throw new Error(`Failed to fetch models from ${provider.provider}: ${lastStatus} ${lastStatusText}`)
}
function normalizeCatalog(kind: CatalogKind, rows: unknown[]): RemoteCatalogModel[] {
const inferCaps =
kind === 'openai'
? inferOpenAICapabilities
: kind === 'gemini'
? inferGeminiCapabilities
: inferAnthropicCapabilities
const parsed: RemoteCatalogModel[] = []
for (const raw of rows) {
if (!raw || typeof raw !== 'object') continue
const row = raw as Record<string, unknown>
const id = typeof row.id === 'string' ? row.id : null
if (!id) continue
const caps = inferCaps(id)
if (!caps) continueView on GitHub (pinned to 7205d770c1)