{"record":{"id":"8c462bc14eafe14f","repo":"janhq/jan","slug":"catalog-not-supported-for-provider-provider","errorCode":null,"errorMessage":"Catalog not supported for ${provider.provider}","messagePattern":"Catalog not supported for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web-app/src/lib/remoteModelCatalog.ts","lineNumber":202,"sourceCode":"    body = await response.json()\n  } catch {\n    body = null\n  }\n  return {\n    ok: response.ok,\n    status: response.status,\n    statusText: response.statusText,\n    body,\n  }\n}\n\nexport async function fetchTopRemoteModels(\n  provider: ProviderLike,\n  fetchImpl: FetchImpl\n): Promise<RemoteCatalogModel[]> {\n  const kind = resolveCatalogKind(provider)\n  if (!kind) {\n    throw new Error(`Catalog not supported for ${provider.provider}`)\n  }\n  if (!provider.base_url) {\n    throw new Error('Provider must have base_url configured')\n  }\n\n  const keyChain = providerRemoteApiKeyChain(provider)\n  const attempts: (string | undefined)[] = keyChain.length > 0 ? keyChain : [undefined]\n\n  let lastStatus = 0\n  let lastStatusText = ''\n  for (let i = 0; i < attempts.length; i++) {\n    const result = await getJson(\n      fetchImpl,\n      `${provider.base_url}/models`,\n      buildHeaders(provider, attempts[i])\n    )\n    lastStatus = result.status\n    lastStatusText = result.statusText","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/lib/remoteModelCatalog.ts#L184-L220","documentation":"Thrown by fetchTopRemoteModels when resolveCatalogKind(provider) returns null/undefined, i.e. the provider does not map to a known catalog flavor (openai / gemini / anthropic). The function refuses to guess a catalog format and aborts before any network call (remoteModelCatalog.ts:202).","triggerScenarios":"Calling fetchTopRemoteModels with a provider whose provider/api_type does not resolve to one of the three supported catalog kinds — e.g. a generic 'openai-compatible' custom provider, a local llamacpp/mlx provider, or a mistral/xai/cohere provider that resolveCatalogKind does not whitelist.","commonSituations":"User added a custom OpenAI-compatible provider and the catalog refresh tried to list its models; the provider name was renamed/typoed so it no longer matches the whitelist; calling fetchTopRemoteModels on a local engine provider.","solutions":["Only call fetchTopRemoteModels for providers resolveCatalogKind recognizes (openai/gemini/anthropic-compatible).","If the custom provider speaks the OpenAI /models schema, ensure its api_type or provider name resolves to 'openai' in resolveCatalogKind.","Skip the catalog refresh (hide the 'browse models' action) for unsupported providers rather than letting it throw.","Extend resolveCatalogKind's whitelist if the provider genuinely supports one of the catalog shapes."],"exampleFix":"// before\nconst kind = resolveCatalogKind(provider)\nif (!kind) throw new Error(`Catalog not supported for ${provider.provider}`)\n// after: caller checks capability before calling\nif (!supportsRemoteCatalog(provider)) {\n  return []  // catalog UI hides itself for this provider\n}\nreturn await fetchTopRemoteModels(provider, fetchImpl)","handlingStrategy":"type-guard","validationCode":"function supportsRemoteCatalog(provider: ProviderLike): boolean {\n  return resolveCatalogKind(provider) !== null\n}\n// before calling fetchTopRemoteModels:\nif (!supportsRemoteCatalog(provider)) return []","typeGuard":"function isCatalogKind(k: unknown): k is CatalogKind {\n  return k === 'openai' || k === 'gemini' || k === 'anthropic'\n}","tryCatchPattern":"try {\n  return await fetchTopRemoteModels(provider, fetchImpl)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Catalog not supported')) return []\n  throw e\n}","preventionTips":["Check resolveCatalogKind before offering the 'browse models' action in the UI.","Hide the catalog tab for local providers (llamacpp/mlx) entirely.","Whitelist only providers whose /models schema matches openai/gemini/anthropic.","Re-resolve the catalog kind after a provider rename to avoid stale kind caches."],"tags":["catalog","provider","validation","typescript"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}