decolua/9router · error
Unknown provider: ${providerInput}
Error message
Unknown provider: ${providerInput} What it means
handleSingleProviderSearch normalizes the caller-supplied provider string via resolveProviderId and looks it up in the AI_PROVIDERS registry. If the resolved id has no registry entry, the provider is unknown and a 400 'Unknown provider: <input>' is returned. The registry is config-driven (providers/registry/*), so only registered search-capable provider ids resolve.
Source
Thrown at src/sse/handlers/search.js:99
models: comboModels,
handleSingleModel: (b, m) => handleSingleProviderSearch(b, m, request, apiKey, settings),
log,
comboName: providerInput,
comboStrategy,
comboStickyLimit
});
}
return handleSingleProviderSearch(body, providerInput, request, apiKey, settings);
}
async function handleSingleProviderSearch(body, providerInput, request, apiKey, settings) {
const query = body.query;
const providerId = resolveProviderId(providerInput);
const resolvedProvider = AI_PROVIDERS[providerId];
if (!resolvedProvider) {
log.warn("SEARCH", "Unknown provider", { provider: providerInput });
return errorResponse(HTTP_STATUS.BAD_REQUEST, `Unknown provider: ${providerInput}`);
}
const providerConfig = resolvedProvider.searchConfig;
const supportsSearch = !!providerConfig || !!resolvedProvider.searchViaChat;
if (!supportsSearch) {
log.warn("SEARCH", "Provider does not support web search", { provider: providerId });
return errorResponse(HTTP_STATUS.BAD_REQUEST, `Provider ${providerId} does not support web search`);
}
if (providerInput !== providerId) {
log.info("ROUTING", `${providerInput} → ${providerId}`);
} else {
log.info("ROUTING", `Provider: ${providerId}`);
}
// Sanitized body forwarded to coreView on GitHub (pinned to 90b52e06ff)
Solutions
- Use an exact registered provider id from AI_PROVIDERS (open-sse/providers/registry/) in the `provider`/`model` field.
- If you meant a combo, verify the combo name matches an entry in getCombos() and that its models array is non-empty.
- Check for typos and case; run resolveProviderId semantics (e.g. lowercase) against the input.
- After adding a new registry file, regenerate providers/registry/index.js with scripts/migrate-registry.mjs — hand-edits leave the provider unregistered.
- Update the client after upgrading 9Router, since provider ids can change between versions.
Example fix
// before
const body = { provider: 'Tavily Search', query: q }; // display name
// after
const body = { provider: 'tavily', query: q }; // registered provider id Defensive patterns
Strategy: validation
Validate before calling
import { AI_PROVIDERS, resolveProviderId } from '@/shared/constants/providers.js';
if (!AI_PROVIDERS[resolveProviderId(provider)]) {
throw new Error(`Unknown provider: ${provider}. Valid: ${Object.keys(AI_PROVIDERS).join(', ')}`);
} Type guard
const isKnownProvider = (p) => Boolean(AI_PROVIDERS[resolveProviderId(String(p))]);
Prevention
- Derive provider ids from the registry at build time instead of hardcoding strings.
- After adding registry files, run scripts/migrate-registry.mjs to regenerate registry/index.js.
- Keep a validated list of provider ids in your client config.
When it happens
Trigger: Posting search with provider/model set to a typo ('tavilyy'), a display name instead of an id ('Google Search'), a combo name that fails getComboModelsFromData (name mismatch or combo has no models) and then fails provider resolution, or a provider removed/renamed in a newer version of the registry.
Common situations: Version mismatch between client config and server provider registry; copy-pasting model strings (containing '/') that are not combos; using a chat-only provider id with a '-search' suffix appended wrongly; stale cached dashboard state referencing a deleted provider.
Related errors
- Provider ${providerId} does not support web search
- Unknown provider: ${providerInput}
- Provider ${providerId} does not support web fetch
- Missing required field: provider (or model)
- Missing required field: query
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/c04dbdf7035c3697.
Report an issue: GitHub.