twentyhq/twenty · error · Error

${res.statusText}: ${await res.text()}

Error message

${res.statusText}: ${await res.text()}

What it means

Thrown by the Genql-generated fetcher inside twenty-client-sdk when the GraphQL endpoint returns a non-2xx HTTP status. The error message concatenates res.statusText with the raw response body (await res.text()), so the actual server error text is included. This is the genql runtime's lowest-level HTTP failure path before any JSON parsing is attempted.

Source

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

                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
        }
    }

    if (!batch) {
        return async (body) => {
            const json = await fetcher!(body)
            if (Array.isArray(json)) {
                return json.map((json) => {
                    if (json?.errors?.length) {
                        throw new GenqlError(json.errors || [], json.data)
                    }
                    return json.data
                })
            } else {
                if (json?.errors?.length) {

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Inspect the full error message: the part after the colon is the raw server body — read it to get the real cause.
  2. Verify the URL passed to the Twenty client (should point to the GraphQL endpoint, not the REST root).
  3. Confirm the access token is valid and not expired; pass a fresh token via headers or the client constructor.
  4. Check that the Twenty backend is reachable from the runtime environment (network/VPN/proxy/CORS).

Example fix

// before
const client = createClient({ url: 'https://app.twenty.com', headers: {} });
// after
const client = createClient({
  url: 'https://app.twenty.com/graphql',
  headers: { Authorization: `Bearer ${process.env.TWENTY_ACCESS_TOKEN}` },
});
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const data = await client.someQuery();
} catch (err) {
  // Genql raw HTTP error: `${statusText}: ${body}` — parse on the first colon
  const [statusText, ...rest] = err.message.split(':');
  console.error('GraphQL HTTP failure:', statusText.trim(), rest.join(':'));
}

Prevention

When it happens

Trigger: Calling any generated genql client query/mutation where the POST to the GraphQL URL receives res.ok === false (e.g. 401, 403, 404, 500, 502). The check at fetcher.ts:52 is `if (!res.ok)` and runs only for the single (non-batched) fetcher path.

Common situations: Wrong baseUrl passed to createClient; the Twenty server is down or behind a misconfigured proxy that returns HTML/JSON error pages; expired or missing Authorization token causing 401; CORS preflight failure surfacing as an opaque error response; hitting a path that is not the GraphQL endpoint.

Related errors


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