n8n-io/n8n · error · NodeApiError
500
500
Error message
Timeout reached
What it means
During async polling (e.g. for batch operations or assistant runs), the pollUntilAvailable helper loops calling request() at intervalSeconds intervals. If the total elapsed time reaches timeoutSeconds before the check() predicate passes, it throws a NodeApiError with code 500. Note: code 500 is semantically misleading — it represents a client-side timeout, not a server error.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/helpers/polling.ts:18
import type { IExecuteFunctions } from 'n8n-workflow';
import { NodeApiError } from 'n8n-workflow';
export async function pollUntilAvailable<TResponse>(
ctx: IExecuteFunctions,
request: () => Promise<TResponse>,
check: (response: TResponse) => boolean,
timeoutSeconds: number,
intervalSeconds = 5,
): Promise<TResponse> {
const abortSignal = ctx.getExecutionCancelSignal();
let response: TResponse | undefined;
const startTime = Date.now();
while (!response || !check(response)) {
const elapsedTime = Date.now() - startTime;
if (elapsedTime >= timeoutSeconds * 1000) {
throw new NodeApiError(ctx.getNode(), {
message: 'Timeout reached',
code: 500,
});
}
if (abortSignal?.aborted) {
throw new NodeApiError(ctx.getNode(), {
message: 'Execution was cancelled',
code: 500,
});
}
response = await request();
// Wait before the next polling attempt
await new Promise((resolve) => setTimeout(resolve, intervalSeconds * 1000));
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Increase the timeoutSeconds parameter passed to pollUntilAvailable to accommodate longer-running operations
- Check the OpenAI dashboard for the actual job status — it may have completed server-side after the timeout
- Reduce the input size or complexity of the async operation so it finishes faster
- Verify network connectivity and latency to the OpenAI API
Example fix
// before — pollUntilAvailable(ctx, request, check, 60, 5) // after — pollUntilAvailable(ctx, request, check, 300, 10)
Defensive patterns
Strategy: retry
Validate before calling
// Choose timeout based on operation type
const timeoutByOperation = {
fine_tune: 3600, // 1 hour
batch: 7200, // 2 hours
assistant_run: 600, // 10 minutes
};
const timeout = timeoutByOperation[operation] ?? 300;
if (timeout < expectedDuration) {
console.warn(`Timeout ${timeout}s may be too short for ${operation}`);
} Try / catch
try {
await pollUntilAvailable(ctx, request, check, timeoutSeconds, intervalSeconds);
} catch (error) {
if (error instanceof NodeApiError && error.message === 'Timeout reached') {
// Check if the job actually completed server-side
const status = await checkJobStatus(jobId);
if (status === 'completed') return;
throw error;
}
throw error;
} Prevention
- Set timeoutSeconds generously for long operations like fine-tuning
- Monitor job status via the OpenAI dashboard independently of the polling loop
- Use longer intervalSeconds for very long jobs to reduce API calls
- Consider using webhooks instead of polling for job completion if available
When it happens
Trigger: A long-running OpenAI async operation (fine-tune, batch, assistant run) that does not reach a terminal state within the configured timeoutSeconds window. The polling loop checks elapsed time before each iteration and aborts.
Common situations: Fine-tuning jobs that take longer than expected; assistant runs with heavy tool usage that exceed the timeout; network latency inflating poll response times; timeoutSeconds configured too low for the operation.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Video task ${taskId} did not complete within the maximum pol
- Task ${taskId} did not complete within the maximum polling t
- Database connection timed out
- Timed out after ${timeoutMs}ms waiting for database connecti
- Expression timed out after ${this.config.timeout}ms
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/2a9d56effa237bd4.
Report an issue: GitHub.