{"record":{"id":"9be76eb2e5fd292d","repo":"twentyhq/twenty","slug":"response-statustext-response-rawbody","errorCode":null,"errorMessage":"${response.statusText}: ${response.rawBody}","messagePattern":"\\$\\{response\\.statusText\\}: \\$\\{response\\.rawBody\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/twenty-client-sdk/src/generate/twenty-client-template.ts","lineNumber":377,"sourceCode":"  private async resolveHeaders(): Promise<HeadersInit> {\n    if (typeof this.headers === 'function') {\n      return (await this.headers()) ?? {};\n    }\n\n    return this.headers ?? {};\n  }\n\n  private shouldRefreshToken(response: GraphqlResponse): boolean {\n    if (response.status === 401) {\n      return true;\n    }\n\n    return hasAuthenticationErrorInGraphqlPayload(response.payload);\n  }\n\n  private assertResponseIsSuccessful(response: GraphqlResponse) {\n    if (response.status < 200 || response.status >= 300) {\n      throw new Error(`${response.statusText}: ${response.rawBody}`);\n    }\n\n    if (response.payload === null) {\n      throw new Error('Invalid JSON response');\n    }\n\n    return response.payload;\n  }\n\n  private async requestRefreshedAccessToken(): Promise<string | null> {\n    const refreshAccessTokenFunction = (\n      globalThis as {\n        frontComponentHostCommunicationApi?: {\n          requestAccessTokenRefresh?: () => Promise<string>;\n        };\n      }\n    ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;\n","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-client-sdk/src/generate/twenty-client-template.ts#L359-L395","documentation":"Thrown by TwentyClient.assertResponseIsSuccessful (twenty-client-template.ts:375-378) when the GraphQL HTTP response status is outside the 200-2999 range. This runs after token-refresh retry logic, so the error reflects a final, unrecoverable HTTP-level failure. The message combines statusText and the raw (unparsed) response body.","triggerScenarios":"Any GraphQL request whose HTTP status is < 200 or >= 300 after the optional 401 refresh-and-retry path. Common codes: 401 (refresh failed or no refresh hook), 403, 404, 500, 502, 503.","commonSituations":"Expired access token with no frontComponentHostCommunicationApi.requestAccessTokenRefresh hook registered; server-side 500 from a malformed operation; reverse proxy returning 502/504; wrong apiUrl pointing to a non-GraphQL route returning 404; CORS errors producing an opaque 0-status response.","solutions":["Read the rawBody portion of the message — it contains the server's actual error payload.","For 401s, register a token refresh hook on globalThis.frontComponentHostCommunicationApi.requestAccessTokenRefresh or supply a fresh token.","Verify apiUrl correctness and that the Twenty server is up.","Check CORS configuration if running in a browser (opaque responses get status 0)."],"exampleFix":"// before — no refresh hook, 401 surfaces as error\n// after — register a refresh hook before constructing the client\n(globalThis as any).frontComponentHostCommunicationApi = {\n  requestAccessTokenRefresh: async () => refreshTokenPair(),\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const result = await client.someQuery();\n} catch (err) {\n  // message is `${statusText}: ${rawBody}`\n  const colonIdx = err.message.indexOf(':');\n  const statusText = err.message.slice(0, colonIdx);\n  const rawBody = err.message.slice(colonIdx + 2);\n  if (statusText === 'Unauthorized') {\n    await refreshAccessToken();\n  }\n}","preventionTips":["Register a requestAccessTokenRefresh hook for 401 recovery.","Validate apiUrl before constructing the client.","Monitor for 5xx via the catch handler and alert.","Confirm CORS headers when calling cross-origin from a browser."],"tags":["network","graphql","authentication","client-sdk"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}