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

  1. Treat this error as terminal for the execution: release the caller and fail/abort the execution rather than retrying in-place.
  2. Ensure release(caller) is called in the execution's finally block so the dead bridge is returned/discarded.
  3. Prevent the upstream OOM (see error 307) — reduce expression memory use.
  4. 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

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


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/d877f752808f53ee. Report an issue: GitHub.