janhq/jan · error · Error
Failed to fetch model catalog: ${response.status} ${response
Error message
Failed to fetch model catalog: ${response.status} ${response.statusText} What it means
Thrown by ModelService.fetchModelCatalog (default.ts:54) when the HTTP response from MODEL_CATALOG_URL is not OK (response.ok is false). The status and statusText are embedded in the message. This is the inner 'response not ok' branch before JSON parsing; the surrounding catch re-wraps it as error [154].
Source
Thrown at web-app/src/services/models/default.ts:54
export class DefaultModelsService implements ModelsService {
private getEngine(provider: string = defaultProvider) {
return EngineManager.instance().get(provider) as AIEngine | undefined
}
async getModel(modelId: string): Promise<modelInfo | undefined> {
return this.getEngine()?.get(modelId)
}
async fetchModels(): Promise<modelInfo[]> {
return this.getEngine()?.list() ?? []
}
async fetchModelCatalog(): Promise<ModelCatalog> {
try {
const response = await fetch(MODEL_CATALOG_URL)
if (!response.ok) {
throw new Error(
`Failed to fetch model catalog: ${response.status} ${response.statusText}`
)
}
const catalog: ModelCatalog = await response.json()
return catalog
} catch (error) {
console.error('Error fetching model catalog:', error)
throw new Error(
`Failed to fetch model catalog: ${error instanceof Error ? error.message : 'Unknown error'}`
)
}
}
async fetchLatestJanModel(): Promise<CatalogModel | null> {
try {
const response = await fetch(LATEST_JAN_MODEL_URL)
View on GitHub (pinned to fad3f12a14)
Solutions
- Retry — most catalog failures are transient (5xx / CDN).
- Update the app so MODEL_CATALOG_URL points at the current catalog host.
- Check network/proxy: ensure the catalog host is reachable and not blocked by a captive portal or firewall.
- Fall back to the cached catalog if available rather than failing the whole Hub view.
Example fix
// before
if (!response.ok) {
throw new Error(`Failed to fetch model catalog: ${response.status} ${response.statusText}`)
}
// after: retry once on transient errors, then degrade to cached catalog
if (!response.ok) {
if (response.status >= 500 && attempt < 2) { await delay(500); continue }
return getCachedCatalog() ?? throw new Error(`Failed to fetch model catalog: ${response.status} ${response.statusText}`)
} Defensive patterns
Strategy: retry
Validate before calling
async function isCatalogReachable(url: string): Promise<boolean> {
try {
const r = await fetch(url, { method: 'HEAD' })
return r.ok || r.status === 405 // some hosts reject HEAD
} catch { return false }
} Type guard
function isOkResponse(r: Response): boolean {
return r.ok
} Try / catch
for (let attempt = 0; attempt < 2; attempt++) {
try {
const response = await fetch(MODEL_CATALOG_URL)
if (response.ok) return await response.json()
if (response.status < 500) throw new Error(`Failed to fetch model catalog: ${response.status} ${response.statusText}`)
await new Promise(r => setTimeout(r, 500))
} catch (e) { if (attempt === 1) throw e }
} Prevention
- Retry transient (5xx) catalog failures once before surfacing.
- Cache the last successful catalog for offline / degraded mode.
- Keep MODEL_CATALOG_URL current across releases.
- Distinguish status errors from network errors in the surfaced message.
When it happens
Trigger: The remote model catalog endpoint returns a non-2xx status: 404 (catalog URL moved), 500/502/503 (catalog server down), 429 (rate-limited), or a CDN error.
Common situations: Catalog hosting outage; the hardcoded MODEL_CATALOG_URL changed in a new release but the client is old; corporate firewall returns a blocking page with a non-2xx status; transient CDN blip.
Related errors
- Failed to fetch models from ${provider.provider}: ${result.s
- Failed to fetch model catalog: ${error instanceof Error ? er
- Failed to fetch HuggingFace repository: ${response.status} $
- Failed to fetch models from ${provider.provider}: ${lastStat
- Authentication failed: API key is required or invalid for ${
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/f532341fc573d365.
Report an issue: GitHub.