twentyhq/twenty · error · Error

Invalid JSON response

Error message

Invalid JSON response

What it means

Thrown by TwentyClient.assertResponseIsSuccessful (twenty-client-template.ts:380-382) when the response status was 2xx but payload is null. payload is set to null by executeGraphqlRequest (line 341-348) when rawBody is empty or JSON.parse fails — so the body was empty or not valid JSON.

Source

Thrown at packages/twenty-client-sdk/src/generate/twenty-client-template.ts:381

    return this.headers ?? {};
  }

  private shouldRefreshToken(response: GraphqlResponse): boolean {
    if (response.status === 401) {
      return true;
    }

    return hasAuthenticationErrorInGraphqlPayload(response.payload);
  }

  private assertResponseIsSuccessful(response: GraphqlResponse) {
    if (response.status < 200 || response.status >= 300) {
      throw new Error(`${response.statusText}: ${response.rawBody}`);
    }

    if (response.payload === null) {
      throw new Error('Invalid JSON response');
    }

    return response.payload;
  }

  private async requestRefreshedAccessToken(): Promise<string | null> {
    const refreshAccessTokenFunction = (
      globalThis as {
        frontComponentHostCommunicationApi?: {
          requestAccessTokenRefresh?: () => Promise<string>;
        };
      }
    ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;

    if (typeof refreshAccessTokenFunction !== 'function') {
      return null;
    }

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Inspect response.rawBody from the surrounding context (or reproduce the request with curl) to see what the server actually returned.
  2. Check intermediary proxies/CDNs for HTML error pages masquerading as 200.
  3. Ensure the apiUrl points to the GraphQL endpoint, not a generic web route.
  4. Verify Accept/Content-Type negotiation with the Twenty server.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const result = await client.someQuery();
} catch (err) {
  if (err.message === 'Invalid JSON response') {
    // Reproduce with curl to inspect the raw 2xx body returned by the gateway.
  }
}

Prevention

When it happens

Trigger: GraphQL endpoint returns 200 OK with an empty body, or with a non-JSON body (HTML error page, plain text). JSON.parse throws inside the try block, payload stays null, and the success assertion rejects it.

Common situations: Reverse proxy or CDN returning an empty 200 (e.g. successful CORS preflight surfacing as the response); gateway returning an HTML error page with a 200 status; backend bug returning empty body; gzip/encoding mismatch where text() yields nothing parseable.

Understand the failure class

Related errors


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