{"record":{"id":"0ffcbcc31cf5de2f","repo":"can1357/oh-my-pi","slug":"jina-api-response-reported-failure-payload-code","errorCode":null,"errorMessage":"Jina API response reported failure (${payload.code})","messagePattern":"Jina API response reported failure \\((.+?)\\)","errorType":"exception","errorClass":"SearchProviderError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/web/search/providers/jina.ts","lineNumber":86,"sourceCode":"\tconst response = await fetchImpl(requestUrl, {\n\t\theaders,\n\t\tsignal: withHardTimeout(signal, timeoutMs),\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tconst classified = classifyProviderHttpError(\"jina\", response.status, errorText);\n\t\tif (classified) throw classified;\n\t\tthrow new SearchProviderError(\"jina\", `Jina API error (${response.status}): ${errorText}`, response.status);\n\t}\n\n\tconst payload = (await response.json()) as JinaSearchEnvelope | JinaSearchResponse | null;\n\tif (Array.isArray(payload)) return payload;\n\tif (!payload || typeof payload !== \"object\") {\n\t\tthrow new SearchProviderError(\"jina\", \"Jina API returned invalid response: expected an object or array\");\n\t}\n\tif (typeof payload.code === \"number\" && payload.code !== 200) {\n\t\tthrow new SearchProviderError(\"jina\", `Jina API response reported failure (${payload.code})`, payload.code);\n\t}\n\tif (!Array.isArray(payload.data)) {\n\t\tthrow new SearchProviderError(\"jina\", \"Jina API returned invalid response: expected data array\");\n\t}\n\treturn payload.data as JinaSearchResponse;\n}\n\n/** Execute Jina web search. */\nexport async function searchJina(params: JinaSearchParams): Promise<SearchResponse> {\n\tconst numResults = clampNumResults(params.num_results, DEFAULT_NUM_RESULTS, MAX_NUM_RESULTS);\n\tconst keyOrResolver: ApiKey = params.authStorage.resolver(\"jina\", {\n\t\tsessionId: params.sessionId,\n\t});\n\tconst response = await withAuth(\n\t\tkeyOrResolver,\n\t\tapiKey =>\n\t\t\tcallJinaSearch(apiKey, params.query, numResults, params.site, params.signal, params.fetch, params.timeoutMs),\n\t\t{","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/web/search/providers/jina.ts#L68-L104","documentation":"Thrown by callJinaSearch when the Jina search API returns a JSON envelope whose numeric `code` field is not 200. Jina signals API-level failures (auth, quota, bad request) inside a 200-HTTP-response body via this code field, so the provider checks it explicitly and surfaces it as a SearchProviderError carrying the code as status.","triggerScenarios":"Jina returns HTTP 200 but the body is a JinaSearchEnvelope with code != 200 (e.g. 401 unauthorized key, 429 quota exceeded, 400 malformed query). Any call to searchJina that reaches callJinaSearch with such an envelope.","commonSituations":"Expired or revoked JINA_API_KEY; exhausted free-tier credits; sending query parameters Jina rejects; Jina partial outages that return error envelopes instead of HTTP error statuses.","solutions":["Check payload.code in logs and map it: 401/403 -> fix JINA_API_KEY, 429 -> wait/backoff or upgrade plan","Verify the JINA_API_KEY env var is set to a valid current key from Jina","Retry with backoff for transient 5xx codes","Handle the SearchProviderError by falling back to another search provider"],"exampleFix":"// before\nconst results = await searchJina({ query, apiKey });\n// after\ntry {\n  const results = await searchJina({ query, apiKey });\n} catch (err) {\n  if (err instanceof SearchProviderError && err.status === 401) {\n    // refresh JINA_API_KEY before retrying\n  }\n}","handlingStrategy":"try-catch","validationCode":"// before calling: ensure a key exists\nif (!process.env.JINA_API_KEY) throw new Error('JINA_API_KEY not set');","typeGuard":"function isJinaEnvelope(p: unknown): p is { code: number; data?: unknown } {\n  return typeof p === 'object' && p !== null && 'code' in p;\n}","tryCatchPattern":"try {\n  const res = await searchJina({ query, apiKey });\n} catch (err) {\n  if (err instanceof SearchProviderError) {\n    if (err.status === 401 || err.status === 403) refreshJinaKey();\n    else if (err.status === 429) scheduleRetry();\n    else useFallbackProvider();\n  } else throw err;\n}","preventionTips":["Keep JINA_API_KEY valid and rotated before expiry","Monitor Jina quota/credit usage to avoid 429 envelopes","Wrap provider calls with a fallback chain to another search provider","Log payload codes to detect schema drift early"],"tags":["api","http","search-provider","jina"],"backgroundTag":"api-error-response-code","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}