twentyhq/twenty · critical · RestApiClientError
Global `fetch` function is not available, pass a fetch imple
Error message
Global `fetch` function is not available, pass a fetch implementation to `RestApiClient`.
What it means
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.
Source
Thrown at packages/twenty-client-sdk/src/rest/index.ts:273
return null;
})
.finally(() => {
this.refreshAccessTokenPromise = null;
});
}
return this.refreshAccessTokenPromise;
}
private sendRequest(
url: string,
method: string,
body: unknown,
token: string,
requestOptions?: RestApiRequestOptions,
): Promise<Response> {
if (!isDefined(this.fetchImplementation)) {
throw new RestApiClientError(
'Global `fetch` function is not available, pass a fetch implementation to `RestApiClient`.',
);
}
const requestHeaders = new Headers(this.defaultHeaders);
if (isDefined(requestOptions?.headers)) {
new Headers(requestOptions.headers).forEach((value, key) =>
requestHeaders.set(key, value),
);
}
const isFormDataBody =
typeof FormData !== 'undefined' && body instanceof FormData;
const shouldSerializeBody =
isDefined(body) && !isFormDataBody && typeof body !== 'string';
if (isFormDataBody) {View on GitHub (pinned to 1f5dd2bbd2)
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.
Example fix
// before
const client = new RestApiClient({ baseUrl, token });
// after
import fetch from 'node-fetch';
const client = new RestApiClient({ baseUrl, token, fetch }); Defensive patterns
Strategy: validation
Validate before calling
const fetchImpl =
typeof globalThis.fetch === 'function'
? globalThis.fetch
: (await import('node-fetch')).default;
const client = new RestApiClient({ baseUrl, token, fetch: fetchImpl }); Type guard
const hasGlobalFetch = (): boolean => typeof globalThis.fetch === 'function';
Try / catch
try {
await client.get('/rest/objects/contact');
} catch (err) {
if (err instanceof RestApiClientError && err.message.includes('Global `fetch` function is not available')) {
// pass a fetch polyfill to RestApiClient
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Global `fetch` function is not available, pass a fetch imple
- Global `fetch` function is not available, pass a fetch polyf
- Missing API url. Set the `${DEFAULT_API_URL_NAME}` environme
- Missing application access token. Set the `${DEFAULT_APP_ACC
- url or fetcher is required
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/eb5846b8829c1754.
Report an issue: GitHub.