windmill-labs/windmill · error · ApiError
Generic Error: status: ${errorStatus}; status text: ${errorS
Error message
Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody} What it means
When the API returns a non-2xx status that has NO entry in the client's status-to-message map (e.g. unusual/custom codes or statuses not enumerated), the client falls back to this generic message embedding the status, status text, and a JSON-stringified body. The real diagnostic information is in the interpolated errorBody, not the message text itself.
Source
Thrown at backend/windmill-runtime-nativets/src/windmill-client.js:3610
510: "Not Extended",
511: "Network Authentication Required",
...options.errors,
};
const error = errors[result.status];
if (error) {
throw new ApiError(options, result, error);
}
if (!result.ok) {
const errorStatus = result.status ?? "unknown";
const errorStatusText = result.statusText ?? "unknown";
const errorBody = (() => {
try {
return JSON.stringify(result.body, null, 2);
} catch (e) {
return void 0;
}
})();
throw new ApiError(
options,
result,
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
);
}
};
var request = (config, options) => {
return new CancelablePromise(async (resolve2, reject, onCancel) => {
try {
const url = getUrl(config, options);
const formData = getFormData(options);
const body = getRequestBody(options);
const headers = await getHeaders(config, options);
if (!onCancel.isCancelled) {
let response = await sendRequest(
config,
options,
url,View on GitHub (pinned to e474e8803c)
Solutions
- Parse the status, statusText and body from the thrown ApiError's response object — the generic message contains them verbatim.
- If the status is meaningful and recurring, extend the client with options.errors so future errors get a clear message.
- Check what sits between the client and Windmill (proxy, load balancer) for statuses like 520/522.
- Inspect the server-side request logs using the endpoint and trace data from the response body.
Example fix
// before
catch (e) { console.log(e.message); } // 'Generic Error: status: 522; ...'
// after
catch (e) {
if (e instanceof ApiError) {
console.error(`API ${e.status} ${e.statusText}:`, e.body);
} else throw e;
} Defensive patterns
Strategy: type-guard
Type guard
function isApiErrorWithBody(e) { return e instanceof ApiError && e.body !== undefined && e.status !== undefined; } Try / catch
try {
await client.someCall(args);
} catch (e) {
if (isApiErrorWithBody(e)) {
console.error(`Unmapped HTTP ${e.status} (${e.statusText}):`, e.body);
// branch on e.status / e.body.error
} else throw e;
} Prevention
- Always log the ApiError's status and body — the generic message is not the diagnostic.
- Register custom statuses via options.errors when a proxy introduces its own codes.
- Inspect intermediary infrastructure (reverse proxy/gateway) when statuses are non-standard.
When it happens
Trigger: A windmill-client request receives a non-2xx response whose status code is absent from the default errors map and any options.errors overrides — e.g. proxy/CDN-generated codes (520s), custom middleware statuses, or 418 before a custom override.
Common situations: Requests routed through a reverse proxy or API gateway that injects its own error statuses, an OpenAPI spec/codegen mismatch where a documented status wasn't in the generated errors map, or non-JSON error bodies that stringify oddly.
Related errors
- ApiError with mapped HTTP status message (e.g. "Not Found",
- Couldn't fetch resource types from hub ${hubBaseUrl}: ${(awa
- Couldn't fetch resource types from public hub:
- GET assets/graph -> ${res.status}: ${await res.text()}
- GET ${path} -> ${response.status}: ${body}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/047462dae1b091ac.
Report an issue: GitHub.