n8n-io/n8n · error · IsolateError
Isolate for this caller is no longer available
Error message
Isolate for this caller is no longer available
What it means
Thrown as IsolateError('Isolate for this caller is no longer available') by ExpressionEvaluator.getBridge() when the caller's bridge reports bridge.isDisposed(). The most common cause is an OOM (MemoryLimitError, error 307) that killed the isolate mid-execution; once dead, ALL remaining expressions for that caller are expected to fail because recovery is per-execution, not per-expression. This is distinct from error 309 (whole evaluator disposed) — here only this caller's bridge is gone.
Source
Thrown at packages/@n8n/expression-runtime/src/evaluator/expression-evaluator.ts:144
});
recordOutcome(observability, start, 'success');
return result;
} catch (error) {
recordOutcome(observability, start, 'error', error);
throw error;
}
}
private getBridge(caller: object): RuntimeBridge {
const bridge = this.bridgesByCaller.get(caller);
if (!bridge) {
throw new IsolateError('No bridge acquired for this context. Call acquire() first.');
}
// If the isolate died mid-execution (e.g. OOM), all remaining expressions
// in this execution are expected to fail. Recovery is per-execution, not per-expression.
if (bridge.isDisposed()) {
throw new IsolateError('Isolate for this caller is no longer available');
}
return bridge;
}
async release(caller: object): Promise<void> {
const bridge = this.bridgesByCaller.get(caller);
if (!bridge) return;
this.bridgesByCaller.delete(caller);
await this.pool.release(bridge);
}
async waitForReplenishment(): Promise<void> {
await this.pool.waitForReplenishment();
}
/**
* Transform a template expression to executable JavaScript via tournament.View on GitHub (pinned to 5ac6606e81)
Solutions
- Treat this error as terminal for the execution: release the caller and fail/abort the execution rather than retrying in-place.
- Ensure release(caller) is called in the execution's finally block so the dead bridge is returned/discarded.
- Prevent the upstream OOM (see error 307) — reduce expression memory use.
- If partial recovery is needed, acquire a fresh bridge for a new caller object instead of reusing the dead one.
Example fix
// before — keep evaluating after the isolate died
evaluator.evaluate(hugeExpr, data, caller); // OOM -> MemoryLimitError
evaluator.evaluate(smallExpr, data, caller); // throws IsolateError
// after — abandon the caller after OOM, release it
try {
evaluator.evaluate(hugeExpr, data, caller);
} catch (e) {
if (e instanceof MemoryLimitError) {
await evaluator.release(caller); // drop the dead bridge
// do NOT reuse `caller`; fail the execution or start a new context
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// After any resource error, check the bridge before reusing the caller
function callerIsAlive(evaluator, caller) {
// No public bridge getter; treat MemoryLimitError as fatal for the caller
return true; // see tryCatchPattern for the real guard pattern
} Type guard
import { IsolateError } from '@n8n/errors';
function isCallerDead(e) { return e instanceof IsolateError && /no longer available/i.test(e.message); } Try / catch
import { IsolateError, MemoryLimitError } from '@n8n/errors'; // MemoryLimitError from runtime types
try {
evaluator.evaluate(expr, data, caller);
} catch (e) {
if (e instanceof IsolateError && /no longer available/i.test(e.message)) {
// this caller's isolate died (likely OOM); release and abandon the execution
await evaluator.release(caller);
} else throw e;
} Prevention
- Treat a MemoryLimitError as fatal for that caller: release the bridge immediately.
- Call evaluator.release(caller) in execution finally blocks so dead bridges are returned.
- Do not reuse a caller object after its isolate died; acquire a fresh context.
- Prevent upstream OOM (error 307) by bounding expression memory use.
When it happens
Trigger: After an expression on a caller triggers MemoryLimitError (or otherwise disposes the bridge), a subsequent evaluator.evaluate() call with the same caller object hits getBridge(), finds bridge.isDisposed() true, and throws. Also fired if the isolate was disposed externally while the caller still holds a reference.
Common situations: A workflow execution where expression #1 OOMs and expression #2 (same execution/caller) then fails with this error. A test that disposes a bridge manually but keeps calling evaluate(). A long execution that loses its isolate partway through.
Related errors
- Expression timed out after ${this.config.timeout}ms
- Expression exceeded memory limit of ${this.config.memoryLimi
- Expression evaluation failed: ${errorMessage}
- Evaluator disposed
- ${toolName} requires resumeSubAgent and cancelSubAgent to be
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/d877f752808f53ee.
Report an issue: GitHub.