twentyhq/twenty · error · Error

Global `fetch` function is not available, pass a fetch polyf

Error message

Global `fetch` function is not available, pass a fetch polyfill to Genql `createClient`

What it means

Generated gengl code: when no custom `fetcher` is provided, the SDK builds one on top of a `fetch` implementation. If the global `fetch` is undefined (the runtime has no native fetch and no polyfill was passed via the `fetch` option), it throws because it has no way to perform the POST. This is an environment/polyfill issue, not a network or URL issue.

Source

Thrown at packages/twenty-client-sdk/src/generate/genql/runtime/fetcher.ts:38

export const createFetcher = ({
    url,
    headers = {},
    fetcher,
    fetch: _fetch,
    batch = false,
    ...rest
}: ClientOptions): Fetcher => {
    if (!url && !fetcher) {
        throw new Error('url or fetcher is required')
    }
    if (!fetcher) {
        fetcher = async (body) => {
            let headersObject =
                typeof headers == 'function' ? await headers() : headers
            headersObject = headersObject || {}
            if (typeof fetch === 'undefined' && !_fetch) {
                throw new Error(
                    'Global `fetch` function is not available, pass a fetch polyfill to Genql `createClient`',
                )
            }
            let fetchImpl = _fetch || fetch
            const res = await fetchImpl(url!, {
                headers: {
                    'Content-Type': 'application/json',
                    ...headersObject,
                },
                method: 'POST',
                body: JSON.stringify(body),
                ...rest,
            })
            if (!res.ok) {
                throw new Error(`${res.statusText}: ${await res.text()}`)
            }
            const json = await res.json()
            return json

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Run on Node 18+ (which provides a global `fetch` via undici).
  2. Pass an explicit fetch implementation to `createClient`, e.g. `createClient({ url, fetch: require('node-fetch') })` or pass `cross-fetch`/`undici`'s fetch.
  3. If a bundler is stripping/aliasing fetch, configure it to keep the global or inject a polyfill.
  4. Confirm the environment actually exposes `fetch` (a quick `typeof fetch` check) before constructing the client.

Example fix

// before
const client = createClient({ url: endpoint, headers });
// throws on Node <18: "Global `fetch` function is not available..."

// after
import { fetch as undiciFetch } from 'undici';
const client = createClient({
  url: endpoint,
  headers,
  fetch: typeof fetch === 'undefined' ? undiciFetch : fetch,
});
Defensive patterns

Strategy: validation

Validate before calling

if (typeof fetch === 'undefined' && !customFetch) {
  throw new Error('No global fetch and no polyfill provided to createClient');
}
const client = createClient({ url: endpoint, headers, fetch: customFetch });

Type guard

const hasFetchAvailable = (opts: Partial<ClientOptions>): boolean =>
  typeof fetch === 'function' || typeof opts.fetch === 'function';

Prevention

When it happens

Trigger: Running the SDK in an old Node version (<18, before global `fetch`), in a JS environment without a native fetch, in a bundler config that did not polyfill fetch, or in SSR/build contexts where `fetch` is not defined — and the caller did not pass a `fetch` polyfill to `createClient`.

Common situations: Upgrading/downgrading the Node runtime; running generated SDK code in a bare test harness; a bundler tree-shaking or aliasing `fetch`; executing during a build step where the fetch global is absent.

Related errors


AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12). Data as JSON: /api/errors/272496376d9e1732. Report an issue: GitHub.