Significant-Gravitas/AutoGPT · error · ApiError

HTTP

Error message

HTTP ${response.status}

What it means

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.

Solutions

  1. Catch ApiError and branch on err.status — it's attached even when the message is generic.
  2. 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.
  3. For HTTP/2 servers, expect empty statusText — ensure the backend always returns a JSON error body ({detail: ...}) so the message is informative.
  4. Check console.error output from this same code path: it logs status, method, relative URL, and responseData together — that's the fastest diagnosis.

Example fix

// before
catch (e) { toast({ description: e.message }); } // shows "HTTP 502"

// after
import { ApiError } from "@/lib/autogpt-server-api/helpers";
catch (e) {
  if (e instanceof ApiError && e.status === 401) { /* re-auth flow */ return; }
  toast({ description: e instanceof Error ? e.message : "Request failed" });
}
Defensive patterns

Strategy: type-guard

Type guard

import { ApiError } from "@/lib/autogpt-server-api/helpers";

function isApiError(err: unknown): err is ApiError {
  return err instanceof ApiError;
}

function isAuthExpired(err: unknown): boolean {
  return isApiError(err) && (err.status === 401 || err.status === 403);
}

Try / catch

try {
  await someGeneratedHook.trigger(...);
} catch (error) {
  if (isApiError(error)) {
    switch (error.status) {
      case 401: /* re-auth */ break;
      case 422: /* validation: read error.response.detail */ break;
      default: toast({ description: error.message });
    }
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/84d768323ff34f70. Report an issue: GitHub.

Appendix: source

Thrown at autogpt_platform/frontend/src/app/api/mutators/custom-mutator.ts:151

    const errorMessage =
      responseData?.detail ||
      responseData?.message ||
      response.statusText ||
      `HTTP ${response.status}`;

    console.error(
      `Request failed ${environment.isServerSide() ? "on server" : "on client"}`,
      {
        status: response.status,
        method,
        url: fullUrl.replace(baseUrl, ""), // Show relative URL for cleaner logs
        errorMessage,
        responseData: responseData || "No response data",
      },
    );

    throw new ApiError(errorMessage, response.status, responseData);
  }

  const responseData = await getBody<T["data"]>(response);

  // Transform ISO date strings to Date objects in the response data
  const transformedData = transformDates(responseData);

  return {
    status: response.status,
    data: transformedData,
    headers: response.headers,
  } as T;
};

View on GitHub (pinned to 9c8bb5550f)