{"record":{"id":"8aa64c12c533889e","repo":"decolua/9router","slug":"provider-providerid-does-not-support-web-fetch","errorCode":null,"errorMessage":"Provider ${providerId} does not support web fetch","messagePattern":"Provider (.+?) does not support web fetch","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"src/sse/handlers/fetch.js","lineNumber":126,"sourceCode":"\n  return handleSingleProviderFetch(body, providerInput, request, apiKey, settings);\n}\n\nasync function handleSingleProviderFetch(body, providerInput, request, apiKey, settings) {\n  const targetUrl = body.url;\n  const format = body.format;\n  const maxCharacters = body.max_characters;\n  const providerId = resolveProviderId(providerInput);\n  const resolvedProvider = AI_PROVIDERS[providerId];\n\n  if (!resolvedProvider) {\n    log.warn(\"FETCH\", \"Unknown provider\", { provider: providerInput });\n    return errorResponse(HTTP_STATUS.BAD_REQUEST, `Unknown provider: ${providerInput}`);\n  }\n\n  const providerConfig = resolvedProvider.fetchConfig;\n  if (!providerConfig) {\n    log.warn(\"FETCH\", \"Provider does not support web fetch\", { provider: providerId });\n    return errorResponse(HTTP_STATUS.BAD_REQUEST, `Provider ${providerId} does not support web fetch`);\n  }\n\n  if (providerInput !== providerId) {\n    log.info(\"ROUTING\", `${providerInput} → ${providerId}`);\n  } else {\n    log.info(\"ROUTING\", `Provider: ${providerId}`);\n  }\n\n  // No-auth fetch path (kept for parity though no current fetch provider sets noAuth)\n  if (resolvedProvider.noAuth) {\n    log.info(\"AUTH\", `\\x1b[32m${providerId} no-auth mode\\x1b[0m`);\n    const result = await handleFetchCore({\n      url: targetUrl,\n      format,\n      maxCharacters,\n      provider: resolvedProvider.id,\n      providerConfig,","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/sse/handlers/fetch.js#L108-L144","documentation":"The provider resolved successfully but its registry entry has no fetchConfig, meaning the upstream does not support web fetch (URL content extraction). The fetch pipeline needs provider-specific config (endpoint, auth mode, response parsing) which only fetch-capable providers define, so the handler rejects with HTTP 400 'Provider <id> does not support web fetch'.","triggerScenarios":"Sending a chat-only provider (e.g. an OpenAI-compatible endpoint with no fetch integration) to the fetch endpoint; a provider whose registry entry lacks fetchConfig; routing through a combo whose member is not fetch-capable.","commonSituations":"Assuming every configured provider supports URL extraction like it supports chat; a newly added custom provider missing its fetchConfig block; a combo mixing fetch and non-fetch providers.","solutions":["Switch to a provider that supports web fetch (one with fetchConfig in open-sse/providers/registry) such as jina or exa","If you own the provider definition, add a fetchConfig block to its registry entry to enable fetch","Check the dashboard's provider capabilities to see which providers are fetch-enabled","For combos, ensure every model in the combo is fetch-capable or pick a fetch-only combo"],"exampleFix":"// before\n{ model: 'my-openai-compatible-provider', url: 'https://example.com' }\n// after\n{ model: 'jina', url: 'https://example.com' }  // a fetch-capable provider","handlingStrategy":"fallback","validationCode":"const FETCH_CAPABLE = new Set(['jina', 'exa', 'firecrawl']); // ids with fetchConfig in open-sse/providers/registry\nif (!FETCH_CAPABLE.has(model)) {\n  console.warn(`${model} has no fetchConfig - falling back to a fetch-capable provider`);\n  model = 'jina';\n}","typeGuard":null,"tryCatchPattern":"let res = await fetch(endpoint, { method: 'POST', body: JSON.stringify({ model, url }) });\nif (res.status === 400 && (await res.clone().text()).includes('does not support web fetch')) {\n  res = await fetch(endpoint, { method: 'POST', body: JSON.stringify({ model: 'jina', url }) }); // fallback provider\n}","preventionTips":["Maintain a client-side allowlist of fetch-capable provider ids and pick from it","Check provider capabilities in the dashboard before routing fetch traffic to a provider","For combos, verify every member provider is fetch-capable","When adding a custom provider, add fetchConfig to its registry entry if it should support fetch"],"tags":["http-400","unsupported-feature","provider-registry","web-fetch"],"backgroundTag":"unsupported-operation","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}