Skip to content

cargo-test aborts with a stack overflow on every PR — statically_reachable_trusted_js_package_is_aot_compiled_without_route_entry, and a Python-only diff reproduces it #9196

Description

@proggeramlug

Summary

The cargo-test job is failing on every open PR with a stack overflow, not an assertion:

thread 'commands::compile::collect_modules::tests::
        statically_reachable_trusted_js_package_is_aot_compiled_without_route_entry'
       (12606) has overflowed its stack
fatal runtime error: stack overflow, aborting
process didn't exit successfully: .../perry-c8602d85b11282cb (signal: 6, SIGABRT)

The abort takes down the whole test binary, so every test that had not yet run is skipped — the same masking shape as #9108. The visible failure is one test; the cost is the tail of the run.

It is not caused by any diff

Confirmed on four PRs with unrelated contents, all the same test, all the same signal:

PR contents cargo-test
#9190 perry-runtime only stack overflow
#9191 codegen stack overflow
#9185 codegen FAILURE
#9193 scripts/ci_e2e_scope.py only — zero Rust stack overflow

#9193 is the decisive one: it changes a single Python file, cannot affect the compiled test binary at all, and reproduces the abort identically. Whatever the cause is, it is on main.

What is known

  • The test is from fix(compile): AOT-promote trusted reachable JavaScript #8529 (fix(compile): AOT-promote trusted reachable JavaScript) and long predates any of these PRs.
  • It lives in crates/perry/src/commands/compile/collect_modules/tests.rs:604.
  • It is a debug build (target/debug/build/perry/...), where stack frames are largest and no inlining trims recursion depth.
  • Stack overflow rather than assertion failure points at unbounded or deep recursion in module collection / reachability walking, not at a wrong expected value.

I have not root-caused it. This issue records that it is reproducible, that it is not diff-caused, and that a one-file Python PR is a free reproducer for whoever picks it up.

Why this is worth prioritising

Two required gates are red on main at once right now — this one and e2e-scoped (fixed in #9193). A permanently-red required check is CLAUDE.md hazard 2: it teaches reviewers to merge past red, and the next real regression lands invisibly behind it. The stack-overflow shape makes that worse than a normal failure, because it silently truncates the rest of the suite.

Suggested first steps

  1. Confirm determinism: re-run cargo test -p perry --bin perry statically_reachable_trusted on main at 84185b5656 and see whether it aborts every time or intermittently. If intermittent, the trigger is likely test ordering or a shared fixture, not the test itself.
  2. RUST_MIN_STACK bisection will say how deep the recursion is, and whether it is deep-but-bounded (a threshold problem) or unbounded (a cycle in the reachability walk — e.g. a package graph that re-enters itself when a subpath resolves back to its own root).
  3. If it is a cycle, the fix is a visited-set in the walk, and the regression test is the package shape that closes the loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions