{"record":{"id":"84d768323ff34f70","repo":"Significant-Gravitas/AutoGPT","slug":"http-response-status","errorCode":null,"errorMessage":"HTTP ${response.status}","messagePattern":"HTTP \\$\\{response\\.status\\}","errorType":"http","errorClass":"ApiError","httpStatus":null,"severity":"error","filePath":"autogpt_platform/frontend/src/app/api/mutators/custom-mutator.ts","lineNumber":151,"sourceCode":"\n    const errorMessage =\n      responseData?.detail ||\n      responseData?.message ||\n      response.statusText ||\n      `HTTP ${response.status}`;\n\n    console.error(\n      `Request failed ${environment.isServerSide() ? \"on server\" : \"on client\"}`,\n      {\n        status: response.status,\n        method,\n        url: fullUrl.replace(baseUrl, \"\"), // Show relative URL for cleaner logs\n        errorMessage,\n        responseData: responseData || \"No response data\",\n      },\n    );\n\n    throw new ApiError(errorMessage, response.status, responseData);\n  }\n\n  const responseData = await getBody<T[\"data\"]>(response);\n\n  // Transform ISO date strings to Date objects in the response data\n  const transformedData = transformDates(responseData);\n\n  return {\n    status: response.status,\n    data: transformedData,\n    headers: response.headers,\n  } as T;\n};\n","sourceCodeStart":133,"sourceCodeEnd":165,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/frontend/src/app/api/mutators/custom-mutator.ts#L133-L165","documentation":"This is the custom mutator used by every Orval-generated React Query call: on any non-ok response it builds errorMessage from responseData.detail → responseData.message → response.statusText → `HTTP ${status}` (the literal shown is the LAST fallback, used when the body is unparseable AND statusText is empty), then throws ApiError(errorMessage, status, responseData). ApiError (src/lib/autogpt-server-api/helpers.ts:11) carries .status and .response for programmatic handling. Seeing the bare 'HTTP nnn' form means the server returned no parseable body and no status text.","triggerScenarios":"Any generated API hook hitting a non-2xx: 401 session expiry, 404 wrong ID, 422 validation errors (these carry detail and show FastAPI text instead), 500s with empty bodies (proxy cut the connection, backend crashed mid-response) — the literal 'HTTP nnn' specifically requires detail/message absent and empty statusText.","commonSituations":"Backend container down behind a proxy returning 502 with an HTML body that fails getBody parsing; HTTP/2 responses where statusText is always empty (so the fallback fires for any JSON-less error); CORS-blocked error bodies in local dev.","solutions":["Catch ApiError and branch on err.status — it's attached even when the message is generic.","Reproduce the request in DevTools/curl and read the raw body: if it's HTML, fix the proxy/backend path; if JSON-with-detail, the message will already be specific once the body parses.","For HTTP/2 servers, expect empty statusText — ensure the backend always returns a JSON error body ({detail: ...}) so the message is informative.","Check console.error output from this same code path: it logs status, method, relative URL, and responseData together — that's the fastest diagnosis."],"exampleFix":"// before\ncatch (e) { toast({ description: e.message }); } // shows \"HTTP 502\"\n\n// after\nimport { ApiError } from \"@/lib/autogpt-server-api/helpers\";\ncatch (e) {\n  if (e instanceof ApiError && e.status === 401) { /* re-auth flow */ return; }\n  toast({ description: e instanceof Error ? e.message : \"Request failed\" });\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"import { ApiError } from \"@/lib/autogpt-server-api/helpers\";\n\nfunction isApiError(err: unknown): err is ApiError {\n  return err instanceof ApiError;\n}\n\nfunction isAuthExpired(err: unknown): boolean {\n  return isApiError(err) && (err.status === 401 || err.status === 403);\n}","tryCatchPattern":"try {\n  await someGeneratedHook.trigger(...);\n} catch (error) {\n  if (isApiError(error)) {\n    switch (error.status) {\n      case 401: /* re-auth */ break;\n      case 422: /* validation: read error.response.detail */ break;\n      default: toast({ description: error.message });\n    }\n  }\n}","preventionTips":["Always instanceof-check ApiError in mutation onError handlers — .status and .response are richer than .message.","Ensure the backend returns JSON error bodies ({detail}) on every failure path so the generic 'HTTP nnn' fallback never fires.","Read the mutator's console.error log line (status + method + relative URL + body) before debugging blind."],"tags":["api-client","orval","react-query","http-status","error-handling"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}