Expression engine VM mode bugs fixed for webhooks
Workflows with expression variables now work correctly in VM sandbox mode — webhook activation, conflict detection, and expression evaluation no longer fail silently or throw errors.
Expression variables like $execution, $vars, $secrets, and the node selector function $() are now properly available in VM-isolated expression evaluation. Several code paths that handle webhook registration, conflict checking, and workflow activation were bypassing the isolate pool, causing expressions to fail or return undefined in sandboxed environments. These paths now correctly acquire and release isolates, ensuring consistent expression resolution across all execution modes.
View Original GitHub DescriptionFact Check
Summary
Fix two classes of bugs surfaced by e2e testing with N8N_EXPRESSION_ENGINE=vm.
e2e run: https://github.com/n8n-io/n8n/actions/runs/23856758598
Missing isolate acquisition in CLI code paths
Some code paths that evaluate expressions were calling into the expression engine without first acquiring an isolate from the pool. This caused failures (or silent wrong results) in VM mode for:
- Webhook registration during workflow activation, in
active-workflow-manager.ts - Webhook conflict checks on save, in
workflow.service.ts - Test webhook registration, in
test-webhooks.ts - Webhook deactivation, in
active-workflow-manager.ts
Each path now wraps the relevant call in acquireIsolate() / releaseIsolate().
Missing globals in VM isolate
The isolate-side resetDataProxies() was not exposing several variables that tournament-transformed expressions expect to find on __data. When missing, tournament's "$foo" in this ? this.$foo : global.$foo check fell through to global.$foo (also undefined), silently returning undefined or throwing.
Added to __data and globalThis:
$execution,$vars,$secrets— as lazy proxies$()— node-selector function backed by a deep lazy proxy$executionId,$resumeWebhookUrl,$webhookId,$nodeId,$nodeVersion— fetched as primitives via the host callback
Related Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/CAT-2529
Review / Merge checklist
- PR title and summary are descriptive. (conventions)
- Docs updated or follow-up ticket created.
- Tests included.
- PR Labeled with
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported)