Skip to content

Bug: SDK HttpClient throws raw SyntaxError instead of Context7Error on non-JSON error responses #1964

@marlonbarreto-git

Description

@marlonbarreto-git

Bug Description

The SDK's HttpClient.request() method calls res.json() without a try/catch in the error-response path. When the server returns a non-JSON error body (HTML 502 gateway page, plain-text 429, Cloudflare challenge page, etc.), res.json() throws a native SyntaxError that bypasses the Context7Error type system.

Affected Code

File: packages/sdk/src/http/index.ts, lines ~171-173

if (!res.ok) {
  const errorBody = (await res.json()) as { error?: string; message?: string };
  throw new Context7Error(errorBody.error || errorBody.message || res.statusText);
}

res.json() is called bare — no try/catch, no Content-Type guard.

Impact

  • Any caller using catch (error) { if (error instanceof Context7Error) ... } will miss the error entirely
  • Infrastructure errors (Cloudflare 502, AWS ALB 503, rate limiting 429 with HTML body) surface as confusing SyntaxError: Unexpected token '<' at position 0 instead of a typed error with the HTTP status
  • This affects all SDK consumers: the CLI, the MCP server, and any third-party integration using the SDK

Steps to Reproduce

  1. Configure Context7 SDK to point to a server that returns a non-JSON error
  2. (Or simulate: proxy returning HTML 502 on the API endpoint)
  3. Call any SDK method (e.g., resolveLibraryId)
  4. Observe: SyntaxError: Unexpected token '<' instead of Context7Error

Proposed Solution

Wrap res.json() in a try/catch:

if (!res.ok) {
  const errorBody = await res.json().catch(() => ({})) as { error?: string; message?: string };
  throw new Context7Error(errorBody.error || errorBody.message || res.statusText);
}

This is a one-line change (adding .catch(() => ({}))) that ensures non-JSON error bodies gracefully fall through to the res.statusText fallback message, and the error is always a typed Context7Error.

Happy to submit a PR for this fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions