{"record":{"id":"c04dbdf7035c3697","repo":"decolua/9router","slug":"unknown-provider-providerinput-c04dbd","errorCode":null,"errorMessage":"Unknown provider: ${providerInput}","messagePattern":"Unknown provider: (.+?)","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"src/sse/handlers/search.js","lineNumber":99,"sourceCode":"      models: comboModels,\n      handleSingleModel: (b, m) => handleSingleProviderSearch(b, m, request, apiKey, settings),\n      log,\n      comboName: providerInput,\n      comboStrategy,\n      comboStickyLimit\n    });\n  }\n\n  return handleSingleProviderSearch(body, providerInput, request, apiKey, settings);\n}\n\nasync function handleSingleProviderSearch(body, providerInput, request, apiKey, settings) {\n  const query = body.query;\n  const providerId = resolveProviderId(providerInput);\n  const resolvedProvider = AI_PROVIDERS[providerId];\n\n  if (!resolvedProvider) {\n    log.warn(\"SEARCH\", \"Unknown provider\", { provider: providerInput });\n    return errorResponse(HTTP_STATUS.BAD_REQUEST, `Unknown provider: ${providerInput}`);\n  }\n\n  const providerConfig = resolvedProvider.searchConfig;\n  const supportsSearch = !!providerConfig || !!resolvedProvider.searchViaChat;\n\n  if (!supportsSearch) {\n    log.warn(\"SEARCH\", \"Provider does not support web search\", { provider: providerId });\n    return errorResponse(HTTP_STATUS.BAD_REQUEST, `Provider ${providerId} does not support web search`);\n  }\n\n  if (providerInput !== providerId) {\n    log.info(\"ROUTING\", `${providerInput} → ${providerId}`);\n  } else {\n    log.info(\"ROUTING\", `Provider: ${providerId}`);\n  }\n\n  // Sanitized body forwarded to core","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/sse/handlers/search.js#L81-L117","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst body = { provider: 'Tavily Search', query: q }; // display name\n// after\nconst body = { provider: 'tavily', query: q }; // registered provider id","handlingStrategy":"validation","validationCode":"import { AI_PROVIDERS, resolveProviderId } from '@/shared/constants/providers.js';\nif (!AI_PROVIDERS[resolveProviderId(provider)]) {\n  throw new Error(`Unknown provider: ${provider}. Valid: ${Object.keys(AI_PROVIDERS).join(', ')}`);\n}","typeGuard":"const isKnownProvider = (p) => Boolean(AI_PROVIDERS[resolveProviderId(String(p))]);","tryCatchPattern":null,"preventionTips":["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."],"tags":["http-400","provider-registry","configuration","web-search"],"backgroundTag":"unknown-provider","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}