{"record":{"id":"0173baf9c0535870","repo":"OtterMind/Chat2DB","slug":"fetch-failed-with-status-response-status","errorCode":null,"errorMessage":"Fetch failed with status ${response.status}","messagePattern":"Fetch failed with status (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"chat2db-community-client/src/components/SSERequest/sseFetch.ts","lineNumber":56,"sourceCode":"  }\n\n  /** ---------------------- fetch ---------------------- */\n  let response = await fetchFn(...fetchArgs);\n\n  /** ---------------------- response middleware ---------------------- */\n  if (typeof middlewares.onResponse === 'function') {\n    const modifiedResponse = await middlewares.onResponse(response);\n\n    if (!(modifiedResponse instanceof Response)) {\n      throw new TypeError('The options.onResponse must return a Response instance!');\n    }\n\n    response = modifiedResponse;\n  }\n\n  /** ---------------------- response check ---------------------- */\n  if (!response.ok) {\n    throw new TypeError(`Fetch failed with status ${response.status}`);\n  }\n\n  if (!response.body) {\n    throw new TypeError('The response body is empty.');\n  }\n\n  /** ---------------------- return ---------------------- */\n  return response;\n};\n\nexport default SSEFetch;\n","sourceCodeStart":38,"sourceCodeEnd":68,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-client/src/components/SSERequest/sseFetch.ts#L38-L68","documentation":"sseFetch throws a TypeError when the HTTP response status is not ok (outside 2xx range). This is the response-validation gate for SSE/JSON requests made to the AI streaming endpoint. It fires after fetch resolves but before body parsing, so 4xx/5xx errors from the AI backend surface here. The error includes the numeric status for diagnostics.","triggerScenarios":"The AI backend returns HTTP 401 (bad API key), 403 (forbidden), 429 (rate limited), 500 (server error), or 502/503 (upstream down) during an SSE stream POST. Also triggered by a proxy or gateway returning an error HTML page.","commonSituations":"Expired or invalid AI API key. Rate limiting from the LLM provider. Backend service down or misconfigured reverse proxy. CORS/network errors manifesting as a non-ok status.","solutions":["Inspect response.status in the catch to show a user-appropriate message (auth, rate-limit, server error).","Verify the AI API key and baseURL are correct and current.","Retry with backoff on 429/5xx status codes.","Check backend logs and reverse proxy configuration if status is 502/503."],"exampleFix":"// before\nconst response = await sseFetch(baseURL, requestInit);\n\n// after\nlet response;\ntry {\n  response = await sseFetch(baseURL, requestInit);\n} catch (e) {\n  if (e instanceof TypeError && /Fetch failed with status/.test(e.message)) {\n    const status = parseInt(e.message.match(/\\d+/)?.[0] || '0', 10);\n    showError(status === 429 ? 'Rate limited, try later' : 'AI request failed');\n    return;\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isFetchStatusError(e: unknown): e is TypeError {\n  return e instanceof TypeError && /Fetch failed with status/.test(e.message);\n}\n\nfunction extractStatus(e: TypeError): number {\n  return parseInt(e.message.match(/\\d+/)?.[0] || '0', 10);\n}","tryCatchPattern":"try {\n  const response = await sseFetch(baseURL, requestInit);\n} catch (e) {\n  if (isFetchStatusError(e)) {\n    const status = extractStatus(e);\n    if (status === 429) return retryWithBackoff();\n    if (status === 401) return refreshApiKey();\n    onError(`AI request failed (${status})`);\n    return;\n  }\n  throw e;\n}","preventionTips":["Validate API keys and endpoint URL before initiating SSE requests.","Implement exponential backoff for 429 and 5xx responses.","Monitor AI backend health and fail fast with a user-friendly message."],"tags":["sse","ai","network","http","frontend"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}