Skip to content

turbopack: ignore deferred circuit breaker cycles - #98929

Draft
lukesandberg wants to merge 1 commit into
codex/side-effects/late-edgesfrom
codex/side-effects/circuit-breaker-edges
Draft

lukesandberg wants to merge 1 commit into
codex/side-effects/late-edgesfrom
codex/side-effects/circuit-breaker-edges

Conversation

@lukesandberg

@lukesandberg lukesandberg commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Export circuit breakers protect evaluation cycles by exposing lazy export getters before module execution. A cycle that closes only through a deferred module edge cannot be traversed during evaluation, so applying circuit-breaker code generation to it adds unnecessary early export setup and getters.

This change reuses the evaluation timing recorded on module-reference binding metadata when selecting circuit-breaker cycles. The cycle detector still considers only parallel, used edges, and now also excludes edges proven to execute after their parent module finishes evaluating. Deferred references remain in every reachability, export-usage, chunking, and runtime-loading path; only evaluation-cycle detection is narrowed.

Separate scope-hoisting fixtures pin both sides of the behavior: a cycle closed by a deferred require() uses normal bottom-of-factory value exports, while an all-eager cycle retains early getter initialization.

Verification

  • cargo test -p turbopack-core module_graph --lib
  • cargo nextest run -p turbopack-tests -E 'test(snapshot) | test(/circuit_breaker_(deferred|eager)_edge/) | test(/side_effect_optimization|side_effects_optimization/) | test(/async_modules/) | test(/execution__turbopack__scope_hoisting/) | test(/cjs_remove_unused_imports/)'
  • cargo check -p turbopack-core -p turbopack-ecmascript -p turbopack-tests

@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Failing test suites

Commit: e6b43fb | About building and testing Next.js

pnpm test-dev-experimental-turbo test/development/app-dir/lazy-dynamic-imports/lazy-dynamic-imports.test.ts (turbopack) (Experimental) (job)

  • lazy-dynamic-imports > does not parse a dynamic import target before activation (DD)
Expand output

● lazy-dynamic-imports › does not parse a dynamic import target before activation

expect(received).toContain(expected) // indexOf

Matcher error: received value must not be null nor undefined

Received has value: null

  257 |         await browser.elementByCss('#load-parse-error').click()
  258 |         await waitForRedbox(browser)
> 259 |         expect(await getRedboxSource(browser)).toContain(
      |                                                ^
  260 |           'parse-error-proves-target-was-analyzed'
  261 |         )
  262 |       } finally {

  at Object.toContain (development/app-dir/lazy-dynamic-imports/lazy-dynamic-imports.test.ts:259:48)

@lukesandberg lukesandberg changed the title turbopack: ignore deferred circuit breaker edges turbopack: ignore deferred circuit breaker cycles Sep 19, 2026
@lukesandberg
lukesandberg added this pull request to stack #98930 September 19, 2026 05:25
@lukesandberg
lukesandberg force-pushed the codex/side-effects/circuit-breaker-edges branch from 9ddf016 to fff8442 Compare September 19, 2026 19:27
@lukesandberg
lukesandberg force-pushed the codex/side-effects/circuit-breaker-edges branch from fff8442 to 27e6a81 Compare September 21, 2026 05:49
Co-authored-by: Luke Sandberg <210140+lukesandberg@users.noreply.github.com>
@lukesandberg
lukesandberg force-pushed the codex/side-effects/circuit-breaker-edges branch from 27e6a81 to e6b43fb Compare September 21, 2026 05:50

This branch has not been deployed

No deployments
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.

1 participant