{"record":{"id":"cb6db3d4e0450cfa","repo":"sipeed/picoclaw","slug":"provider-q-does-not-support-model-listing","errorCode":null,"errorMessage":"provider %q does not support model listing","messagePattern":"provider %q does not support model listing","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"web/backend/api/models.go","lineNumber":659,"sourceCode":"\n\tvar req struct {\n\t\tProvider   string `json:\"provider\"`\n\t\tAPIKey     string `json:\"api_key\"`\n\t\tAPIBase    string `json:\"api_base\"`\n\t\tModelIndex *int   `json:\"model_index,omitempty\"`\n\t}\n\tif err = json.Unmarshal(body, &req); err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Invalid JSON: %v\", err), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif req.Provider == \"\" {\n\t\thttp.Error(w, \"provider is required\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif !providers.IsModelProviderFetchable(req.Provider) {\n\t\thttp.Error(w, fmt.Sprintf(\"provider %q does not support model listing\", req.Provider), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tapiKey := strings.TrimSpace(req.APIKey)\n\tapiBase := strings.TrimSpace(req.APIBase)\n\n\tif apiKey == \"\" && req.ModelIndex != nil {\n\t\tif stored := h.lookupStoredAPIKey(*req.ModelIndex, req.Provider, apiBase); stored != \"\" {\n\t\t\tapiKey = stored\n\t\t}\n\t}\n\n\tif apiBase == \"\" {\n\t\tapiBase = providers.DefaultAPIBaseForProtocol(req.Provider)\n\t}\n\tif apiBase == \"\" {\n\t\thttp.Error(w, fmt.Sprintf(\"No default API base for provider %q\", req.Provider), http.StatusBadRequest)\n\t\treturn","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/web/backend/api/models.go#L641-L677","documentation":"Returned by POST /api/models/fetch when provider is non-empty but providers.IsModelProviderFetchable(provider) is false. Only providers exposing an upstream /models listing endpoint (OpenAI-compatible, Anthropic, etc.) are fetchable; providers without a model-listing API (e.g. OAuth-only or single-model providers) are rejected with 400 rather than attempted.","triggerScenarios":"POST /api/models/fetch with {\"provider\": \"elevenlabs\"} or any provider lacking a list-models endpoint; using a custom provider id that the backend never registered; typo like \"openai-compatible\" instead of the registered id.","commonSituations":"UI offers every provider in the add-model dropdown but only some support listing; version skew where a newer frontend knows a provider the older backend does not; user pastes a provider name from docs of a different version.","solutions":["Use a fetchable provider id — query the backend's provider options and look for the listing-enabled flag before enabling the Fetch button","For non-fetchable providers, enter model ids manually instead of fetching the list","Upgrade the backend so its provider registry knows the provider your frontend advertises"],"exampleFix":"// before\nfetch('/api/models/fetch', {method:'POST', body: JSON.stringify({provider: 'elevenlabs'})})\n\n// after\nconst providers = await getProviderOptions();\nconst fetchable = providers.filter(p => p.model_listing_supported);\n// only offer `fetchable` ids to the fetch-models flow","handlingStrategy":"validation","validationCode":"const providerOptions = await getProviderOptions(); // backend-sourced list\nconst fetchable = providerOptions.filter((p: any) => p.model_listing_supported);\nif (!fetchable.some(p => p.id === chosenProvider)) {\n  throw new Error(`provider ${chosenProvider} does not support model listing — enter model ids manually`);\n}","typeGuard":"function isFetchableProvider(id: string, options: {id: string; model_listing_supported: boolean}[]): boolean {\n  return options.some(o => o.id === id && o.model_listing_supported);\n}","tryCatchPattern":"try {\n  const res = await fetch('/api/models/fetch', {...});\n  if (res.status === 400 && (await res.text()).includes('does not support model listing')) {\n    /* hide the Fetch action for this provider; fall back to manual model entry */\n  }\n} catch (e) { /* network */ }","preventionTips":["Gate the Fetch button on the provider's listing capability flag from the API","Keep frontend and backend provider registries in sync (same version)","Offer manual model-id entry as the fallback path for non-fetchable providers"],"tags":["http","validation","provider","model-listing"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}