{"record":{"id":"3ae4a604323a3d5d","repo":"n8n-io/n8n","slug":"failed-to-fetch-provider-catalog-response-statu","errorCode":null,"errorMessage":"Failed to fetch provider catalog: ${response.statusText}","messagePattern":"Failed to fetch provider catalog: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/catalog.ts","lineNumber":165,"sourceCode":" *\n * Returns a map of provider ID → ProviderInfo with all available models.\n * The catalog is fetched once and can be cached by the caller.\n *\n * @example\n * ```typescript\n * import { fetchProviderCatalog } from '@n8n/agents';\n *\n * const catalog = await fetchProviderCatalog();\n * console.log(Object.keys(catalog)); // ['anthropic', 'openai', ...]\n * console.log(catalog.anthropic.models['claude-sonnet-4-5'].reasoning); // true\n * ```\n */\nexport async function fetchProviderCatalog(options?: {\n\tsignal?: AbortSignal;\n}): Promise<ProviderCatalog> {\n\tconst response = await fetch(MODELS_DEV_URL, { signal: options?.signal });\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch provider catalog: ${response.statusText}`);\n\t}\n\n\tconst data = modelsDevCatalogSchema.parse(await response.json());\n\tconst catalog: ProviderCatalog = {};\n\n\tfor (const [key, rawProvider] of Object.entries(data)) {\n\t\tconst providerResult = modelsDevProviderSchema.safeParse(rawProvider);\n\t\tif (!providerResult.success) continue;\n\t\tconst provider = providerResult.data;\n\t\tif (!provider.models || Object.keys(provider.models).length === 0) continue;\n\n\t\tconst models: Record<string, ModelInfo> = {};\n\t\tfor (const [modelId, rawModel] of Object.entries(provider.models)) {\n\t\t\tconst modelResult = modelsDevModelSchema.safeParse(rawModel);\n\t\t\tif (!modelResult.success) continue;\n\t\t\tconst model = modelResult.data;\n\t\t\t// Deprecated models still 404 at call time when the provider retires\n\t\t\t// them, so never offer them.","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/catalog.ts#L147-L183","documentation":"fetchProviderCatalog GETs https://models.dev/api.json and throws when the response is not ok, embedding response.statusText. Used by Agent/model resolution to look up provider metadata (cost, modalities, reasoning flag) from models.dev.","triggerScenarios":"Any non-2xx response from models.dev: 4xx/5xx, proxy auth required (407), rate limited (429), or service outage (503). Also triggered when a transparent proxy returns an error status for the catalog host.","commonSituations":"Corporate egress proxy blocks or rewrites models.dev; air-gapped environments; models.dev temporarily down; captive portal intercepting HTTPS; custom fetch override returning an error status.","solutions":["Retry with backoff — models.dev outages are usually transient.","Allow-list https://models.dev in your proxy/firewall and verify with curl.","Pass an AbortSignal with a sane timeout and handle failure by falling back to a cached catalog.","Provide your own fetch implementation via options.fetch that points to a mirrored catalog."],"exampleFix":"// before\nconst catalog = await fetchProviderCatalog();\n// after\nlet catalog;\ntry {\n  catalog = await fetchProviderCatalog({ signal: AbortSignal.timeout(8000) });\n} catch (e) {\n  catalog = await loadCachedCatalog(); // graceful fallback\n}","handlingStrategy":"retry","validationCode":"async function fetchCatalogSafe() {\n  const response = await fetch('https://models.dev/api.json', { signal: AbortSignal.timeout(8000) });\n  if (!response.ok) throw new Error(`preflight status ${response.status}`);\n  return response;\n}","typeGuard":null,"tryCatchPattern":"let catalog;\ntry {\n  catalog = await fetchProviderCatalog({ signal: AbortSignal.timeout(8000) });\n} catch (e) {\n  catalog = loadCachedCatalog();\n  if (!catalog) throw e;\n}","preventionTips":["Cache the catalog locally after first successful fetch.","Allow-list models.dev in corporate proxies; verify reachability during onboarding.","Provide options.fetch with retry/timeout for production telemetry paths."],"tags":["network","catalog","models-dev","fetch"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}