{"record":{"id":"8dd12a0e8f387453","repo":"windmill-labs/windmill","slug":"failed-to-fetch-models-for-provider-provider","errorCode":null,"errorMessage":"Failed to fetch models for provider ${provider}","messagePattern":"Failed to fetch models for provider (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/lib.ts","lineNumber":270,"sourceCode":"\t\t})\n\t}\n\n\t// Standard provider handling\n\tconst endpoint = 'models'\n\tconst models = await fetch(\n\t\t`${location.origin}${OpenAPI.BASE}/w/${workspace}/ai/proxy/${endpoint}`,\n\t\t{\n\t\t\tsignal,\n\t\t\theaders: {\n\t\t\t\t'X-Resource-Path': resourcePath,\n\t\t\t\t'X-Provider': provider,\n\t\t\t\t...(provider === 'anthropic' ? { 'anthropic-version': '2023-06-01' } : {})\n\t\t\t}\n\t\t}\n\t)\n\tif (!models.ok) {\n\t\tconsole.error('Failed to fetch models for provider', provider, models)\n\t\tthrow new Error(`Failed to fetch models for provider ${provider}`)\n\t}\n\n\tconst data = (await readListing(models, maxBytes)) as { data: ModelResponse[] }\n\tif (data.data.length > 0) {\n\t\tconst sortFunc = (provider: AIProvider) => (a: string, b: string) => {\n\t\t\t// First prioritize models in defaultModels array\n\t\t\tconst defaultModels = AI_PROVIDERS[provider]?.defaultModels || []\n\t\t\tconst aInDefault = defaultModels.includes(a)\n\t\t\tconst bInDefault = defaultModels.includes(b)\n\n\t\t\tif (aInDefault && !bInDefault) return -1\n\t\t\tif (!aInDefault && bInDefault) return 1\n\t\t\treturn 0\n\t\t}\n\t\tswitch (provider) {\n\t\t\tcase 'openai':\n\t\t\t\treturn data.data\n\t\t\t\t\t.filter(","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/lib.ts#L252-L288","documentation":"For all non-Bedrock providers, fetchAvailableModels requests the OpenAI-compatible `models` listing through Windmill's AI proxy, forwarding the provider and resource path (plus anthropic-version for Anthropic). A non-ok response is logged and rethrown as this Error naming the provider. It means the provider rejected the credential/endpoint used by the proxy.","triggerScenarios":"GET /w/<workspace>/ai/proxy/models returns non-ok for providers like openai, anthropic, groq, mistral, openrouter, togetherai, deepseek, azure: invalid API key in the provider resource, 401/403 from the vendor, wrong base URL for customai endpoints, quota/billing issues, or vendor outage (5xx).","commonSituations":"Expired or revoked API keys; customai resource pointing at a base URL without a /models route; Azure resource missing deployment config; rate-limited or unpaid account; typo'd provider resource selection in the chat settings.","solutions":["Check console/network for the proxy response body to see the vendor's error (401 vs 404 vs 429)","Re-enter/rotate the API key in the provider resource and test it","For customai, verify the resource's base URL exposes an OpenAI-compatible /models endpoint","Fix billing/quota on the vendor account, or retry on transient 5xx"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  models = await fetchAvailableModels(res, ws, provider, signal)\n} catch (e) {\n  notifyUser(`Model listing failed for ${provider}: check the provider resource API key`)\n  models = AI_PROVIDERS[provider]?.defaultModels ?? []\n}","preventionTips":["Test the provider API key in the resource editor before chatting","For customai, confirm the base URL serves an OpenAI-compatible /models route","Watch vendor status pages and quota/billing; 429/402 surface here","Cache a known-good model list to degrade gracefully on outages"],"tags":["network","ai-providers","api-key","proxy","authentication"],"backgroundTag":"model-list-fetch-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}