n8n-io/n8n · error · ApiError
Request failed (${response.status})
Error message
Request failed (${response.status}) What it means
Thrown by N8nClient.request() when response.ok is false (status >= 400) AND the error response body lacks a recognizable 'message' field. The fallback message includes the raw status code. When the server returns a structured {message: '...'} body, that message is used instead — this fires only when the body is unstructured or non-JSON.
Source
Thrown at packages/@n8n/cli/src/client.ts:153
`Connection error: ${msg}. Check the URL and ensure the instance is running.`,
);
}
this.debug?.(`← ${response.status} ${response.statusText} (${Date.now() - start}ms)`);
if (!response.ok) {
const errorBody = await this.readBody(response);
const message =
typeof errorBody === 'object' && errorBody !== null && 'message' in errorBody
? String((errorBody as Record<string, unknown>).message)
: `Request failed (${response.status})`;
const hint =
response.status === 401
? "Check your API key. Run 'n8n-cli config set-api-key <key>' or set N8N_API_KEY."
: response.status === 404
? 'Resource not found. Verify the ID is correct.'
: undefined;
throw new ApiError(response.status, message, hint, errorBody);
}
options.onResponse?.(response);
if (response.status === 204) {
return undefined as T;
}
if (options.responseType === 'binary') {
return Buffer.from(await response.arrayBuffer()) as T;
}
return (await this.readBody(response)) as T;
}
private async readBody(response: Response): Promise<unknown> {
const contentType = response.headers.get('content-type') ?? '';
return contentType.includes('application/json') ? await response.json() : await response.text();View on GitHub (pinned to 5ac6606e81)
Solutions
- Check ApiError.statusCode and ApiError.hint for guidance
- For 401: set a valid API key via 'n8n-cli config set-api-key <key>' or N8N_API_KEY
- For 404: verify the resource ID exists and the endpoint path is correct
- For 5xx: check the n8n server logs for the underlying error
- Inspect ApiError.details for the raw error body
Defensive patterns
Strategy: try-catch
Type guard
import { ApiError } from './client';
function isApiError(e: unknown): e is ApiError {
return e instanceof ApiError;
} Try / catch
try {
return await client.getWorkflow(id);
} catch (e) {
if (e instanceof ApiError) {
switch (e.statusCode) {
case 401: throw new Error('API key invalid. Run: n8n-cli config set-api-key <key>');
case 404: throw new Error(`Workflow ${id} not found`);
case 429: throw new Error('Rate limited. Retry later.');
default: throw new Error(`API error ${e.statusCode}: ${e.message}`);
}
}
throw e;
} Prevention
- Keep the API key current and validate it at startup
- Verify resource IDs exist before making calls when possible
- Handle specific status codes (401, 404, 429, 5xx) with appropriate recovery logic
When it happens
Trigger: Any API call returns 4xx/5xx with a non-JSON body or a JSON body without a message field: 500 with an HTML error page, 502/504 from a reverse proxy, 413 with empty body, 429 with a plain-text rate-limit notice.
Common situations: Invalid resource ID (404 but server returns no message), server crash (500 with HTML), rate limiting (429), API version mismatch, payload too large.
Related errors
- Failed to list ${provider} models (status ${response.status}
- LangSmith mode requires `--dataset` and does not support `--
- LangSmith client not initialized - check LANGSMITH_API_KEY
- Webhook request failed: ${response.status} ${response.status
- Failed to fetch templates: ${response.status} ${response.sta
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/cceaaf3fbeebb720.
Report an issue: GitHub.