upstash/context7 · error · TypeError

A fetch implementation is required

Error message

A fetch implementation is required

What it means

TypeError thrown in the client constructor when neither a custom `fetch` was supplied in the config nor is a global fetch available. The SDK does not polyfill fetch itself; it requires a fetch implementation (native, polyfilled, or injected).

Source

Thrown at packages/sdk/src/http/index.ts:61

  private readonly fetch: Context7Fetch;
  private readonly onResponse?: (metadata: Context7ResponseMetadata) => void;

  public constructor(config: HttpClientConfig) {
    this.options = {
      cache: config.cache,
      signal: config.signal,
      timeout: config.timeout ?? DEFAULT_TIMEOUT,
      keepAlive: config.keepAlive ?? true,
    };
    validateTimeout(this.options.timeout);

    this.baseUrl = config.baseUrl.replace(/\/$/, "");
    if (!isHttpUrl(this.baseUrl)) throw new Context7UrlError(this.baseUrl);

    this.headers = { "Content-Type": "application/json", ...config.headers };
    if (!config.fetch && !globalThis.fetch) {
      throw new TypeError("A fetch implementation is required");
    }
    this.fetch = config.fetch ?? globalThis.fetch.bind(globalThis);
    this.onResponse = config.onResponse;
    this.retry = createRetryPolicy(config.retry);
  }

  public async request<TResult>(request: Context7Request): Promise<Context7Response<TResult>> {
    const method = request.method ?? "POST";
    const abortState = createAbortState(
      [resolveSignal(this.options.signal), request.signal],
      request.timeout ?? this.options.timeout
    );
    const init: RequestInit = {
      cache: normalizeCache(request.cache ?? this.options.cache),
      method,
      headers: this.headers,
      body: request.body === undefined ? undefined : JSON.stringify(request.body),
      keepalive: this.options.keepAlive,

View on GitHub (pinned to 80e681a507)

Solutions

  1. Upgrade to Node.js 18+ where globalThis.fetch is built in.
  2. Explicitly pass fetch in config: new Context7Client({ fetch: require('node-fetch') }) or undici's fetch.
  3. Install and register a fetch polyfill (e.g. undici, node-fetch, cross-fetch) before constructing the client.
  4. In tests, set globalThis.fetch = vi.fn()/jest.fn() stub before client construction.

Example fix

// before
const client = new Context7Client({ baseUrl }); // Node 16: no global fetch
// after
import { fetch as undiciFetch } from 'undici';
const client = new Context7Client({ baseUrl, fetch: undiciFetch });
Defensive patterns

Strategy: fallback

Validate before calling

if (typeof globalThis.fetch !== 'function' && !configFetch) {
  throw new Error('This runtime has no fetch; provide one via Context7Client({ fetch }).');
}

Type guard

function hasFetch(f: unknown): f is typeof fetch {
  return typeof f === 'function';
}

Try / catch

let client: Context7Client;
try {
  client = new Context7Client({ baseUrl });
} catch (e) {
  if (e instanceof TypeError && /fetch implementation/.test(e.message)) {
    const { fetch: polyfill } = await import('undici');
    client = new Context7Client({ baseUrl, fetch: polyfill });
  } else throw e;
}

Prevention

When it happens

Trigger: Instantiating the client in Node.js < 18 (no global fetch), in environments with fetch disabled, or in bundled/test environments where globalThis.fetch is undefined and config.fetch is not provided.

Common situations: Running on Node 16 or older, serverless runtimes without fetch, old test setups (jest without node fetch), or library code that deliberately requires an injected fetch for SSRF/proxy control.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of upstash/context7@80e681a507 (2026-09-08). Data as JSON: /api/errors/9fedfb5236625926. Report an issue: GitHub.