{"record":{"id":"9fedfb5236625926","repo":"upstash/context7","slug":"a-fetch-implementation-is-required","errorCode":null,"errorMessage":"A fetch implementation is required","messagePattern":"A fetch implementation is required","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/sdk/src/http/index.ts","lineNumber":61,"sourceCode":"\n  private readonly fetch: Context7Fetch;\n  private readonly onResponse?: (metadata: Context7ResponseMetadata) => void;\n\n  public constructor(config: HttpClientConfig) {\n    this.options = {\n      cache: config.cache,\n      signal: config.signal,\n      timeout: config.timeout ?? DEFAULT_TIMEOUT,\n      keepAlive: config.keepAlive ?? true,\n    };\n    validateTimeout(this.options.timeout);\n\n    this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n    if (!isHttpUrl(this.baseUrl)) throw new Context7UrlError(this.baseUrl);\n\n    this.headers = { \"Content-Type\": \"application/json\", ...config.headers };\n    if (!config.fetch && !globalThis.fetch) {\n      throw new TypeError(\"A fetch implementation is required\");\n    }\n    this.fetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n    this.onResponse = config.onResponse;\n    this.retry = createRetryPolicy(config.retry);\n  }\n\n  public async request<TResult>(request: Context7Request): Promise<Context7Response<TResult>> {\n    const method = request.method ?? \"POST\";\n    const abortState = createAbortState(\n      [resolveSignal(this.options.signal), request.signal],\n      request.timeout ?? this.options.timeout\n    );\n    const init: RequestInit = {\n      cache: normalizeCache(request.cache ?? this.options.cache),\n      method,\n      headers: this.headers,\n      body: request.body === undefined ? undefined : JSON.stringify(request.body),\n      keepalive: this.options.keepAlive,","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/upstash/context7/blob/80e681a507c5287bc12e483367c40754e29461b9/packages/sdk/src/http/index.ts#L43-L79","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst client = new Context7Client({ baseUrl }); // Node 16: no global fetch\n// after\nimport { fetch as undiciFetch } from 'undici';\nconst client = new Context7Client({ baseUrl, fetch: undiciFetch });","handlingStrategy":"fallback","validationCode":"if (typeof globalThis.fetch !== 'function' && !configFetch) {\n  throw new Error('This runtime has no fetch; provide one via Context7Client({ fetch }).');\n}","typeGuard":"function hasFetch(f: unknown): f is typeof fetch {\n  return typeof f === 'function';\n}","tryCatchPattern":"let client: Context7Client;\ntry {\n  client = new Context7Client({ baseUrl });\n} catch (e) {\n  if (e instanceof TypeError && /fetch implementation/.test(e.message)) {\n    const { fetch: polyfill } = await import('undici');\n    client = new Context7Client({ baseUrl, fetch: polyfill });\n  } else throw e;\n}","preventionTips":["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."],"tags":["fetch","environment","initialization"],"backgroundTag":"missing-dependency","analyzedSha":"80e681a507c5287bc12e483367c40754e29461b9","analyzedAt":"2026-09-08T05:18:41.043Z","contentChangedAt":"2026-09-08T05:18:41.043Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}