{"record":{"id":"277222f6719529aa","repo":"upstash/context7","slug":"errorbody-error-http-error","errorCode":"errorBody.error ?? \"http_error\"","errorMessage":"errorBody.message || errorBody.error || response.statusText","messagePattern":"errorBody\\.message \\|\\| errorBody\\.error \\|\\| response\\.statusText","errorType":"error_code","errorClass":"Context7Error","httpStatus":null,"severity":"error","filePath":"packages/sdk/src/http/response.ts","lineNumber":78,"sourceCode":"\n  if (rawBody) {\n    try {\n      const parsed: unknown = JSON.parse(rawBody);\n      if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n        const { error, message } = parsed as Record<string, unknown>;\n        errorBody = {\n          error: typeof error === \"string\" ? error : undefined,\n          message: typeof message === \"string\" ? message : undefined,\n        };\n      }\n    } catch (cause) {\n      if (response.headers.get(\"content-type\")?.includes(\"application/json\")) {\n        throw jsonParseError(rawBody, metadata, cause, retryable);\n      }\n    }\n  }\n\n  throw new Context7Error(errorBody.message || errorBody.error || response.statusText, {\n    code: errorBody.error ?? \"http_error\",\n    status: response.status,\n    requestId: metadata.requestId,\n    rateLimit: metadata.rateLimit,\n    retryable,\n  });\n}\n\nasync function parseJson(response: Response, metadata: Context7ResponseMetadata): Promise<unknown> {\n  const rawBody = await response.text();\n  try {\n    return JSON.parse(rawBody);\n  } catch (cause) {\n    throw jsonParseError(rawBody, metadata, cause, false);\n  }\n}\n\nfunction jsonParseError(","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/upstash/context7/blob/80e681a507c5287bc12e483367c40754e29461b9/packages/sdk/src/http/response.ts#L60-L96","documentation":"Context7Error thrown by throwResponseError when the server returns a non-OK HTTP response. The message comes from the error body's `message` or `error` field, falling back to response.statusText; the code comes from the body's `error` field, falling back to \"http_error\". Status, requestId, and rate-limit info are attached.","triggerScenarios":"Any request receiving 4xx/5xx: 401 invalid API key, 404 unknown library id, 429 rate limited (code often 'rate_limit'), 500 server errors — whenever the body is not JSON or lacks the fields, message falls back to statusText.","commonSituations":"Expired or wrong API key (401), hitting rate limits (429), requesting a non-existent Context7 library id (404), upstream server outages (5xx).","solutions":["Read err.status and err.code to branch: 401 -> fix credentials, 429 -> back off (use err.rateLimit), 404 -> verify the library id, 5xx -> retry later.","Check err.rateLimit headers to implement client-side rate limiting before the 429 occurs.","Verify your API key is valid and set correctly for authenticated endpoints.","Confirm the library/topic ids passed to queries exist (e.g. list/search first)."],"exampleFix":"// before\nconst res = await client.getLibraryDocs('/websites/react'); // 404 -> Context7Error 'http_error'\n// after\ntry {\n  const res = await client.getLibraryDocs('/websites/react');\n} catch (e) {\n  if (e instanceof Context7Error && e.status === 429) {\n    await sleep(e.rateLimit?.resetMs ?? 60000);\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Validate inputs the API is known to 404 on\nif (!libraryId.startsWith('/')) throw new Error(`libraryId should look like '/websites/react', got: ${libraryId}`);","typeGuard":"function isHttpApiError(e: unknown): e is Context7Error & { status: number } {\n  return e instanceof Context7Error && typeof (e as any).status === 'number';\n}","tryCatchPattern":"try {\n  return await client.getLibraryDocs(id);\n} catch (e) {\n  if (isHttpApiError(e)) {\n    if (e.status === 429) return await retryAfterBackoff(e.rateLimit);\n    if (e.status === 401) throw new Error('Check your Context7 API key');\n    if (e.status === 404) throw new Error(`Unknown library: ${id}`);\n  }\n  throw e;\n}","preventionTips":["Branch on err.status / err.code, not the message string.","Use err.rateLimit to pace requests and avoid 429s.","Validate API keys and library ids before calls.","Monitor err.requestId when filing support issues."],"tags":["http","api-error","status-code"],"backgroundTag":"http-error-response","analyzedSha":"80e681a507c5287bc12e483367c40754e29461b9","analyzedAt":"2026-09-08T05:18:41.043Z","contentChangedAt":"2026-09-08T05:18:41.043Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}