sipeed/picoclaw · error

provider %q does not support model listing

Error message

provider %q does not support model listing

What it means

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.

Source

Thrown at web/backend/api/models.go:659

	var req struct {
		Provider   string `json:"provider"`
		APIKey     string `json:"api_key"`
		APIBase    string `json:"api_base"`
		ModelIndex *int   `json:"model_index,omitempty"`
	}
	if err = json.Unmarshal(body, &req); err != nil {
		http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
		return
	}

	if req.Provider == "" {
		http.Error(w, "provider is required", http.StatusBadRequest)
		return
	}

	if !providers.IsModelProviderFetchable(req.Provider) {
		http.Error(w, fmt.Sprintf("provider %q does not support model listing", req.Provider), http.StatusBadRequest)
		return
	}

	apiKey := strings.TrimSpace(req.APIKey)
	apiBase := strings.TrimSpace(req.APIBase)

	if apiKey == "" && req.ModelIndex != nil {
		if stored := h.lookupStoredAPIKey(*req.ModelIndex, req.Provider, apiBase); stored != "" {
			apiKey = stored
		}
	}

	if apiBase == "" {
		apiBase = providers.DefaultAPIBaseForProtocol(req.Provider)
	}
	if apiBase == "" {
		http.Error(w, fmt.Sprintf("No default API base for provider %q", req.Provider), http.StatusBadRequest)
		return

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Use a fetchable provider id — query the backend's provider options and look for the listing-enabled flag before enabling the Fetch button
  2. For non-fetchable providers, enter model ids manually instead of fetching the list
  3. Upgrade the backend so its provider registry knows the provider your frontend advertises

Example fix

// before
fetch('/api/models/fetch', {method:'POST', body: JSON.stringify({provider: 'elevenlabs'})})

// after
const providers = await getProviderOptions();
const fetchable = providers.filter(p => p.model_listing_supported);
// only offer `fetchable` ids to the fetch-models flow
Defensive patterns

Strategy: validation

Validate before calling

const providerOptions = await getProviderOptions(); // backend-sourced list
const fetchable = providerOptions.filter((p: any) => p.model_listing_supported);
if (!fetchable.some(p => p.id === chosenProvider)) {
  throw new Error(`provider ${chosenProvider} does not support model listing — enter model ids manually`);
}

Type guard

function isFetchableProvider(id: string, options: {id: string; model_listing_supported: boolean}[]): boolean {
  return options.some(o => o.id === id && o.model_listing_supported);
}

Try / catch

try {
  const res = await fetch('/api/models/fetch', {...});
  if (res.status === 400 && (await res.text()).includes('does not support model listing')) {
    /* hide the Fetch action for this provider; fall back to manual model entry */
  }
} catch (e) { /* network */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/cb6db3d4e0450cfa. Report an issue: GitHub.