{"record":{"id":"eb5846b8829c1754","repo":"twentyhq/twenty","slug":"global-fetch-function-is-not-available-pass-a-f-eb5846","errorCode":null,"errorMessage":"Global `fetch` function is not available, pass a fetch implementation to `RestApiClient`.","messagePattern":"Global `fetch` function is not available, pass a fetch implementation to `RestApiClient`\\.","errorType":"exception","errorClass":"RestApiClientError","httpStatus":null,"severity":"critical","filePath":"packages/twenty-client-sdk/src/rest/index.ts","lineNumber":273,"sourceCode":"          return null;\n        })\n        .finally(() => {\n          this.refreshAccessTokenPromise = null;\n        });\n    }\n\n    return this.refreshAccessTokenPromise;\n  }\n\n  private sendRequest(\n    url: string,\n    method: string,\n    body: unknown,\n    token: string,\n    requestOptions?: RestApiRequestOptions,\n  ): Promise<Response> {\n    if (!isDefined(this.fetchImplementation)) {\n      throw new RestApiClientError(\n        'Global `fetch` function is not available, pass a fetch implementation to `RestApiClient`.',\n      );\n    }\n\n    const requestHeaders = new Headers(this.defaultHeaders);\n\n    if (isDefined(requestOptions?.headers)) {\n      new Headers(requestOptions.headers).forEach((value, key) =>\n        requestHeaders.set(key, value),\n      );\n    }\n\n    const isFormDataBody =\n      typeof FormData !== 'undefined' && body instanceof FormData;\n    const shouldSerializeBody =\n      isDefined(body) && !isFormDataBody && typeof body !== 'string';\n\n    if (isFormDataBody) {","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-client-sdk/src/rest/index.ts#L255-L291","documentation":"Thrown by RestApiClient.sendRequest (rest/index.ts:272-276) as a RestApiClientError when this.fetchImplementation is null. The constructor (line 106) sets fetchImplementation to options.fetch ?? globalThis.fetch ?? null, so any runtime without a global fetch that did not pass `fetch` will hit this on the first request.","triggerScenarios":"Using RestApiClient in a runtime that lacks globalThis.fetch (Node < 18, restricted sandboxes) without passing a `fetch` option. The guard fires inside sendRequest on every HTTP call.","commonSituations":"Node 16/17 deployments; test environments without fetch polyfill; SSR in tooling that strips the global; bundled code where fetch was tree-shaken; React Native without a compatible fetch.","solutions":["Pass `fetch` explicitly: `new RestApiClient({ baseUrl, token, fetch: nodeFetch })`.","Upgrade to Node.js 18+ which ships global fetch.","In tests, polyfill globalThis.fetch before constructing the client.","Confirm the polyfill import order runs before instantiation."],"exampleFix":"// before\nconst client = new RestApiClient({ baseUrl, token });\n// after\nimport fetch from 'node-fetch';\nconst client = new RestApiClient({ baseUrl, token, fetch });","handlingStrategy":"validation","validationCode":"const fetchImpl =\n  typeof globalThis.fetch === 'function'\n    ? globalThis.fetch\n    : (await import('node-fetch')).default;\nconst client = new RestApiClient({ baseUrl, token, fetch: fetchImpl });","typeGuard":"const hasGlobalFetch = (): boolean => typeof globalThis.fetch === 'function';","tryCatchPattern":"try {\n  await client.get('/rest/objects/contact');\n} catch (err) {\n  if (err instanceof RestApiClientError && err.message.includes('Global `fetch` function is not available')) {\n    // pass a fetch polyfill to RestApiClient\n  }\n}","preventionTips":["Pass `fetch` explicitly for Node < 18 or sandboxed runtimes.","Pin Node version to 18+.","Polyfill globalThis.fetch in tests before construction.","Import fetch polyfills at module entry."],"tags":["runtime","node","fetch","client-sdk","rest","configuration"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}