Skip to content

fix(core): prevent TLA hang when has_tick_scheduled is set during async module evaluation#33278

Open
bartlomieju wants to merge 1 commit intomainfrom
fix/tla-tick-scheduled-hang
Open

fix(core): prevent TLA hang when has_tick_scheduled is set during async module evaluation#33278
bartlomieju wants to merge 1 commit intomainfrom
fix/tla-tick-scheduled-hang

Conversation

@bartlomieju
Copy link
Copy Markdown
Member

Summary

  • Fix module evaluation promise getting permanently stuck in Pending when has_tick_scheduled is true during async module evaluation with TLA
  • Replace unreachable!() panic with graceful recovery when V8 reports no stalled TLA but evaluation is still pending

Fixes #32821

Root cause

PR #32466 added a has_tick_scheduled() guard to the microtask checkpoint in mod_evaluate (map.rs:1572). For async module graphs with TLA, this checkpoint is critical for draining V8's TLA resume microtasks. When CJS module initialization calls process.nextTick() (setting has_tick_scheduled = true), the checkpoint is skipped, which can leave the evaluation promise permanently Pending in large module graphs.

Changes

libs/core/modules/map.rs -- Primary fix:

  • Always run the microtask checkpoint for async module graphs (is_graph_async), regardless of has_tick_scheduled
  • The nextTick ordering concern only applies to user-visible promise callbacks, not to V8's internal TLA resolution

libs/core/runtime/jsruntime.rs -- Safety net:

  • Replace unreachable!("Expected at least one stalled top-level await") with graceful handling
  • Try one last microtask checkpoint before reporting a stalled TLA
  • If V8 reports no stalled TLAs but evaluation is still pending, retry the event loop iteration instead of panicking

libs/core/modules/tests.rs -- Regression test:

  • test_tla_with_tick_scheduled_no_hang: verifies async module evaluation with TLA completes when has_tick_scheduled is set during evaluation

Test plan

  • New test: test_tla_with_tick_scheduled_no_hang -- async module graph with TLA + tick scheduled
  • Existing test: test_lazy_loaded_esm_with_tla_no_panic -- still passes
  • Existing test: test_stalled_tla -- stalled TLA error reporting still works
  • Manual verification with the reporter's large module graph (500+ ESM modules, ~100 CJS packages)

🤖 Generated with Claude Code

…nc module evaluation

When CJS modules call `process.nextTick()` during module evaluation
(setting `has_tick_scheduled = true`), the guarded microtask checkpoint
in `mod_evaluate` was being skipped for async module graphs with TLA.
This could leave V8's TLA resume microtasks unprocessed, causing the
module evaluation promise to stay permanently Pending.

Two fixes:
1. Always run the microtask checkpoint for async module graphs
   (`is_graph_async`), regardless of `has_tick_scheduled`. The nextTick
   ordering concern that motivates the guard only applies to user-visible
   promise callbacks, not to V8-internal TLA resolution machinery.

2. Replace the `unreachable!()` panic in the stalled TLA check with a
   graceful recovery: try one more microtask checkpoint before reporting,
   and if V8 reports no stalled TLAs but the evaluation is still pending,
   retry the event loop iteration instead of crashing.

Fixes #32821

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deno compile binary hangs during module evaluation on 2.7.5+ (works on 2.7.4)

1 participant