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
- Upgrade to Node.js 18+ where globalThis.fetch is built in.
- Explicitly pass fetch in config: new Context7Client({ fetch: require('node-fetch') }) or undici's fetch.
- Install and register a fetch polyfill (e.g. undici, node-fetch, cross-fetch) before constructing the client.
- 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
- Target Node.js >= 18 or explicitly inject fetch (undici/node-fetch).
- In bundled/test environments, always pass fetch explicitly rather than relying on globals.
- Check globalThis.fetch availability in a startup smoke test.
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.