Skip to content

fix(error): don't capture stack trace on materialized ErrorInstance in appendStackTrace - #34713

Closed
robobun wants to merge 6 commits into
mainfrom
farm/9c06ffc8/fix-appendstacktrace-materialized
Closed

fix(error): don't capture stack trace on materialized ErrorInstance in appendStackTrace#34713
robobun wants to merge 6 commits into
mainfrom
farm/9c06ffc8/fix-appendstacktrace-materialized

Conversation

@robobun

@robobun robobun commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Fuzzilli found a debug assertion failure (fingerprint 667a4a9c2a9a6191):

ASSERTION FAILED: !m_errorInfoMaterialized
vendor/WebKit/Source/JavaScriptCore/runtime/ErrorInstance.cpp(368) : void JSC::ErrorInstance::computeErrorInfo(VM &, bool)

Cause

Error.appendStackTrace(source, destination) calls destination->captureStackTrace() whenever destination->stackTrace() is null, without checking hasMaterializedErrorInfo(). Once an error's .sourceURL/.stack/etc has been accessed, its error info is materialized and its internal m_stackTrace is cleared. Calling captureStackTrace at that point installs a fresh m_stackTrace while m_errorInfoMaterialized stays true, which is an inconsistent state.

Later, during GC, ErrorInstance::finalizeUnconditionally sees the non-null m_stackTrace, finds an unmarked frame, and calls computeErrorInfo, which asserts !m_errorInfoMaterialized.

Repro:

let keep = [];
for (let i = 0; i < 200; i++) {
  eval(`(function inner${i}() {
    const a = new Error();
    const b = new Error();
    a.sourceURL;
    b.sourceURL;
    Error.appendStackTrace(a, b);
    keep.push(b);
  })();`);
}
Bun.gc(true);
Bun.gc(true);

Fix

Skip captureStackTrace when destination has already materialized its error info, matching the existing guard in errorConstructorFuncCaptureStackTrace. Also guard the append against a null destination trace and skip when source == destination (self-appending a WTF::Vector then clearing it is pointless at best).

How did you verify your code works?

Added a subprocess test in test/js/node/v8/capture-stack-trace.test.js that exercises three shapes:

  • materialized source + materialized destination (the original crash)
  • unmaterialized source + materialized destination (covers the null-check guard)
  • self-append on an unmaterialized error (covers the source != destination guard)

Verified the test crashes with exitCode: 134 and ASSERTION FAILED: !m_errorInfoMaterialized on the unfixed debug build and passes with the fix. Also mutation-tested each new guard: removing !hasMaterializedErrorInfo() restores the original assertion, and removing destination->stackTrace() trips a UBSAN null-pointer member call. All 44 tests in the file pass under both ASAN debug and release builds.


[stamp-90s] gate passed · iteration 3 · 2 files touched

fails on main (without fix)
ASAN without fix: 1 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" "test/js/node/v8/capture-stack-trace.test.js"
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
bun test v1.4.0 (dca95ca18)

test/js/node/v8/capture-stack-trace.test.js:
(pass) Regular .stack [12.19ms]
(pass) throw inside Error.prepareStackTrace doesnt crash [6.83ms]
(pass) capture stack trace [6.26ms]
(pass) capture stack trace with message [7.26ms]
(pass) capture stack trace with constructor [4.98ms]
(pass) capture stack trace limit [22.09ms]
(pass) prepare stack trace [11.00ms]
(pass) capture stack trace second argument [17.41ms]
(pass) capture stack trace edge cases [11.36ms]
(pass) Error.captureStackTrace installs .stack as non-enumerable [20.98ms]
(pass) prepare stack trace call sites [12.10ms]
(pass) sanity check [12.97ms]
(pass) CallFrame isEval works as expected [6.70ms]
(pass) CallFrame isTopLevel returns false for Functi
... (truncated)

release without fix: all passed
bun test v1.4.0-canary.1 (801a50530)

test/js/node/v8/capture-stack-trace.test.js:
(pass) Regular .stack [1.13ms]
(pass) throw inside Error.prepareStackTrace doesnt crash [0.13ms]
(pass) capture stack trace [0.10ms]
(pass) capture stack trace with message [0.10ms]
(pass) capture stack trace with constructor [0.09ms]
(pass) capture stack trace limit [0.33ms]
(pass) prepare stack trace [0.16ms]
(pass) capture stack trace second argument [0.29ms]
(pass) capture stack trace edge cases [0.17ms]
(pass) Error.captureStackTrace installs .stack as non-enumerable [0.36ms]
(pass) prepare stack trace call sites [0.18ms]
(pass) sanity check [0.23ms]
(pass) CallFrame isEval works as expected [0.14ms]
(pass) CallFrame isTopLevel returns false for Function constructor [0.15ms]
(pass) CallFrame.p.getThisgetFunction: strict/sloppy mode interaction [0.14ms]
(pass) CallFrame.p.isConstructor [0.05ms]
(pass) CallFrame.p.isNative [0.04ms]
(pass) return non-strings from Error.prepareStackTrace [0.05ms]
(pass) CallFrame.p.toString [0.04ms]
(pass) err.stack should invoke prepareStackTrace [0.34ms]
(pass) Error.prepareStackTrace inside a node:vm works [7.43ms]
(pass) Error.captureStackTrace i
... (truncated)
passes on PR (with fix)
ASAN with fix: all passed
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" "test/js/node/v8/capture-stack-trace.test.js"
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
bun test v1.4.0 (dca95ca18)

test/js/node/v8/capture-stack-trace.test.js:
(pass) Regular .stack [12.72ms]
(pass) throw inside Error.prepareStackTrace doesnt crash [6.69ms]
(pass) capture stack trace [6.36ms]
(pass) capture stack trace with message [7.87ms]
(pass) capture stack trace with constructor [5.26ms]
(pass) capture stack trace limit [23.73ms]
(pass) prepare stack trace [15.80ms]
(pass) capture stack trace second argument [19.15ms]
(pass) capture stack trace edge cases [11.79ms]
(pass) Error.captureStackTrace installs .stack as non-enumerable [21.86ms]
(pass) prepare stack trace call sites [14.67ms]
(pass) sanity check [13.21ms]
(pass) CallFrame isEval works as expected [7.00ms]
(pass) CallFrame isTopLevel returns false for Functi
... (truncated)

release with fix: all passed
$ bun scripts/build.ts --profile=release
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
[configured] bun-profile → bun (stripped) in 809ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/7] cxx obj/unified/UnifiedSource-src_jsc_bindings-1.cpp.o
[2/7] gen cpp.rs (cppbind)
[2/7] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: component rust-std is up to date

  nightly-2026-05-06-x86_64-unknown-linux-gnu unchanged - rustc 1.97.0-nightly (e95e73209 2026-05-05)

info: checking for self-update (current version: 1.29.0)
�[1m�[92m   Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core)
�[1m�[92m   Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno)
�[1m�[92m   Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/s
... (truncated)
diff hotspot
src/jsc/bindings/FormatStackTraceForJS.cpp  |  4 ++--
 test/js/node/v8/capture-stack-trace.test.js | 34 +++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

gate history · 2 passed · 2 rejected · iteration 3

evidence per changed file
file                                         reads  edits  tests
src/jsc/bindings/FormatStackTraceForJS.cpp       2      1      0
test/js/node/v8/capture-stack-trace.test.js      2      2      0

…n appendStackTrace

Error.appendStackTrace(source, destination) called captureStackTrace on
destination when it had no stack frames, without checking whether error
info was already materialized. After accessing .sourceURL/.stack (which
materializes and clears the frames), this left the ErrorInstance with
m_errorInfoMaterialized=true and a non-null m_stackTrace. When GC's
finalizeUnconditionally later found an unmarked frame, computeErrorInfo
hit ASSERT(!m_errorInfoMaterialized).

Skip captureStackTrace when destination is already materialized (matching
errorConstructorFuncCaptureStackTrace), guard the append against a null
destination trace, and skip when source and destination are the same
object.
@robobun

robobun commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 11:06 AM PT - Jul 19th, 2026

@robobun, your commit dca95ca has 4 failures in Build #75786 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 34713

That installs a local version of the PR into your bun-34713 executable, so you can run:

bun-34713 --bun

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

Error stack trace appending now skips destination stack capture when error information is already materialized. A regression test covers repeated appends, self-append, garbage collection, and subprocess completion.

Error stack trace handling

Layer / File(s) Summary
Guard destination stack capture
src/jsc/bindings/FormatStackTraceForJS.cpp
Destination capture requires no existing stack trace and no materialized error information.
Validate materialized-info GC behavior
test/js/node/v8/capture-stack-trace.test.js
A subprocess materializes error information, appends stack traces, forces garbage collection, and verifies successful completion.

Possibly related PRs

  • oven-sh/bun#34408: Updates related materialized error-info handling in FormatStackTraceForJS.cpp.

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main fix to appendStackTrace on materialized ErrorInstance.
Description check ✅ Passed The description covers the problem, cause, fix, repro, and verification, which satisfies the template well enough.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/js/bun/util/error-gc-test.test.js`:
- Around line 65-71: Update the combined assertion in the subprocess test to
include the drained stderr value alongside stdout and exitCode, expecting the
quiet stderr result provided by bunEnv. Preserve the existing Promise.all
collection and assert the complete { stdout, stderr, exitCode } structure.
- Around line 48-73: Extend the regression test’s generated script to cover the
self-append branch by calling Error.appendStackTrace on the same unmaterialized
Error object as both arguments, and retain that object through the existing GC
cycle. Keep the current a-to-b append coverage and ensure the self-appended
object remains reachable until both Bun.gc calls complete.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 67ef93b1-69a8-41fb-aa09-228d94809e03

📥 Commits

Reviewing files that changed from the base of the PR and between 98f6649 and cec75ae.

📒 Files selected for processing (2)
  • src/jsc/bindings/FormatStackTraceForJS.cpp
  • test/js/bun/util/error-gc-test.test.js

Comment thread test/js/bun/util/error-gc-test.test.js Outdated
Comment thread test/js/bun/util/error-gc-test.test.js Outdated
@robobun

robobun commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

Applied both review suggestions in 78d6e60: added self-append coverage (Error.appendStackTrace(self, self) on an unmaterialized error kept through GC) and included stderr in the combined assertion.

robobun added 2 commits July 19, 2026 16:43
error-gc-test.test.js has unrelated tests that time out under the ASAN
debug build; moving to a file that runs clean there.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional findings (outside current diff — PR may have been updated during review):

  • 🟡 test/js/bun/util/error-gc-test.test.js:51-62 — The new && destination->stackTrace() guard on line 675 is load-bearing (it prevents a null-deref when source is unmaterialized but destination is materialized), but neither test shape exercises it: the (a, b) case short-circuits on source->stackTrace() being null, and the (self, self) case has a non-null destination->stackTrace() and short-circuits on source != destination. Consider adding an unmaterialized-source / materialized-destination pair inside the eval'd loop, e.g. const c = new Error(); const d = new Error(); d.sourceURL; Error.appendStackTrace(c, d); keep.push(c, d); — otherwise deleting that guard leaves the test green while re-introducing a null-deref.

    Extended reasoning...

    What the bug is

    The C++ change at FormatStackTraceForJS.cpp:675 adds three new guards to errorConstructorFuncAppendStackTrace:

    1. && !destination->hasMaterializedErrorInfo() on line 671 — skip captureStackTrace when destination is already materialized
    2. && destination->stackTrace() on line 675 — don't dereference a null destination trace
    3. && source != destination on line 675 — skip self-append

    Guard (2) is load-bearing precisely because of guard (1): once guard (1) skips captureStackTrace on a materialized destination, destination->stackTrace() remains null. If source is a fresh unmaterialized error (so source->stackTrace() is non-null), the append block is entered and — without guard (2) — destination->stackTrace()->appendVector(...) dereferences nullptr.

    The regression test added to error-gc-test.test.js covers guards (1) and (3), but not guard (2).

    Step-by-step proof that neither test shape reaches guard (2)

    Shape A — a.sourceURL; b.sourceURL; Error.appendStackTrace(a, b):

    • a.sourceURL materializes a, clearing its m_stackTracesource->stackTrace() is null.
    • Line 675's condition: source->stackTrace() && destination->stackTrace() && source != destination short-circuits on the first conjunct.
    • Guard (2) is never evaluated. Deleting it changes nothing here.

    Shape B — Error.appendStackTrace(self, self) with self unmaterialized:

    • self is fresh; ErrorInstance::finishCreation sets m_stackTrace, so self->stackTrace() is non-null.
    • Line 671: !destination->stackTrace() is false, so captureStackTrace is skipped (irrelevant to guard (2)).
    • Line 675: source->stackTrace() is non-null (true), destination->stackTrace() is non-null (true — guard (2) is trivially satisfied), source != destination is false → block skipped by guard (3).
    • Deleting guard (2) changes nothing here either — it evaluated to true anyway.

    The uncovered shape — d.sourceURL; Error.appendStackTrace(c, d) with c unmaterialized:

    • source = c: fresh, source->stackTrace() non-null.
    • destination = d: materialized via d.sourceURL, so hasMaterializedErrorInfo() is true and stackTrace() is null.
    • Line 671: !destination->stackTrace() (true) && !destination->hasMaterializedErrorInfo() (false) → captureStackTrace skipped by guard (1). destination->stackTrace() remains null.
    • Line 675 with guard (2) present: source->stackTrace() (true) && destination->stackTrace() (false) → block correctly skipped.
    • Line 675 with guard (2) deleted: source->stackTrace() (true) && source != destination (true) → block entered → destination->stackTrace()->appendVector(...) on a null pointer → segfault.

    A grep of test/ shows no other Error.appendStackTrace coverage, so nothing else in the suite would catch a regression here.

    Why this matters

    REVIEW.md ("Prove the test fails for the RIGHT reason") says: "Confirm deleting each load-bearing clause of your fix breaks at least one test — a test that passes both ways is worse than no test." Guard (2) can be removed today without any test failing, which means a future refactor could silently reintroduce a null-deref crash for the (unmaterialized source, materialized destination) input.

    How to fix

    Add a third pair inside the eval'd loop that materializes only the destination:

    const c = new Error();
    const d = new Error();
    d.sourceURL;               // materialize destination only
    Error.appendStackTrace(c, d);
    keep.push(c, d);

    With this in place, deleting && destination->stackTrace() produces an immediate segfault (or ASAN null-deref) in the subprocess and the test fails on exitCode.

    Severity

    nit — the C++ fix itself is correct and nothing breaks on merge; this is a test-coverage gap. It's worth adding since the fix is two lines, but it doesn't need to block.

Exercises the destination->stackTrace() null guard; removing it now fails
the test with a UBSAN null-deref.
@robobun

robobun commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

Added coverage for the unmaterialized-source / materialized-destination shape in 801a505. Verified that deleting the destination->stackTrace() guard now fails the test with a UBSAN null-pointer member call at FormatStackTraceForJS.cpp:676.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No bugs found. The two-line guard change is well-explained and mutation-tested, but it touches JSC ErrorInstance state and GC finalization, and it makes Error.appendStackTrace a silent no-op when the destination is already materialized (rather than eagerly recomputing like errorConstructorFuncCaptureStackTrace does) — worth a maintainer glance to confirm that's the intended semantics.

What was reviewed:

  • Confirmed the hasMaterializedErrorInfo() guard mirrors the existing one in errorConstructorFuncCaptureStackTrace in the same file.
  • Confirmed Error.appendStackTrace has no internal callers in src/js/ (private, non-enumerable, only registered in ZigGlobalObject.cpp), so the no-op-on-materialized behavior change has no downstream effect.
  • Test covers all three new guards (materialized dest, null dest trace, self-append); the stderr: "" assertion under bunEnv was examined and deemed acceptable.
Extended reasoning...

Overview

This PR fixes a Fuzzilli-discovered debug assertion (ASSERTION FAILED: !m_errorInfoMaterialized) in errorConstructorFuncAppendStackTrace. Two conditions are added in src/jsc/bindings/FormatStackTraceForJS.cpp: (1) skip destination->captureStackTrace() when the destination has already materialized its error info, and (2) guard the append against a null destination trace and against source == destination. A subprocess GC-stress test is added to test/js/node/v8/capture-stack-trace.test.js covering three input shapes, and the author mutation-tested each new guard.

Security risks

None. Error.appendStackTrace is a Bun-specific, non-enumerable, ImplementationVisibility::Private function on the Error constructor with no callers in src/js/. The change strictly narrows when captureStackTrace/appendVector run; no new allocation, user-callback, or untrusted-input handling is introduced.

Level of scrutiny

Medium. The diff is tiny and defensive, but it sits at the intersection of JSC ErrorInstance internal state (m_stackTrace, m_errorInfoMaterialized) and GC's finalizeUnconditionally — the exact area REVIEW.md flags as the most-blocked category. The added hasMaterializedErrorInfo() guard is copied directly from errorConstructorFuncCaptureStackTrace a few lines below, which lends confidence, but that sibling function eagerly computes and installs .stack when materialized, whereas this change makes appendStackTrace silently do nothing. That's likely fine for an unused/undocumented API, but it's a design choice a maintainer should ratify rather than a bot.

Other factors

The evidence block shows the test fails on the unfixed ASAN debug build (exit 134 with the expected assertion) and passes on both ASAN debug and release with the fix. CodeRabbit's two suggestions (self-append coverage, stderr in the combined assertion) were addressed in follow-up commits, and a third commit added coverage for the null-destination-trace guard. The verifier agents examined the stderr: "" assertion against REVIEW.md's "never assert stderr is exactly empty" guidance and ruled it out — bunEnv quiets debug logs and the combined-object form is what the guideline recommends. I have no prior review on this PR.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — narrow guard addition that mirrors the existing hasMaterializedErrorInfo() check in errorConstructorFuncCaptureStackTrace.

What was reviewed:

  • Confirmed the new guards only skip work (no new state written), so no new UAF/leak surface; the null-check and self-append guards are each mutation-tested per the PR evidence.
  • Error.appendStackTrace is registered with ImplementationVisibility::Private, undocumented, and unused in src/js/, so the behavioral change (append becomes a no-op when destination is materialized) has no internal callers to affect.
  • Test follows harness conventions (subprocess, bunEnv, concurrent pipe drain, combined assertion) and CodeRabbit feedback was applied.
Extended reasoning...

Overview

Two-line change to errorConstructorFuncAppendStackTrace in src/jsc/bindings/FormatStackTraceForJS.cpp plus a subprocess regression test. The fix adds three guards: (1) skip captureStackTrace on the destination if its error info is already materialized, (2) skip the append if the destination has no stack trace vector, and (3) skip if source and destination are the same object. Guard (1) is the actual crash fix — it prevents installing a fresh m_stackTrace on an ErrorInstance whose m_errorInfoMaterialized is already true, which trips ASSERT(!m_errorInfoMaterialized) in computeErrorInfo during finalizeUnconditionally. Guards (2) and (3) are defensive follow-ons that fall out of (1): once capture can be skipped, the destination trace can legitimately be null at the append site.

Security risks

None. This is a debug-assertion / GC-consistency fix on a private, undocumented static method on the Error constructor. No untrusted input parsing, no allocation size arithmetic, no new code paths that write memory.

Level of scrutiny

Moderate. JSC ErrorInstance / GC-finalizer interaction is memory-safety-adjacent, but this change is strictly subtractive: every added condition only skips an operation that was previously unconditional. Skipping captureStackTrace cannot leak (nothing was allocated) and cannot UAF (nothing is freed). Skipping appendVector/clear likewise. The pattern exactly mirrors the existing hasMaterializedErrorInfo() branch in errorConstructorFuncCaptureStackTrace roughly 120 lines below in the same file, so it's a known-good idiom here rather than a novel design.

Other factors

  • The affected API (Error.appendStackTrace) is registered ImplementationVisibility::Private + DontEnum and has zero callers in src/js/, so the only observable behavior change (append becoming a no-op when the destination's info is already materialized) affects nothing shipped.
  • Evidence in the PR body is strong: fails-on-main / passes-on-PR under ASAN debug, plus per-guard mutation testing (removing !hasMaterializedErrorInfo() restores the original assertion; removing destination->stackTrace() trips a UBSAN null-member-call).
  • The test covers all three guard shapes (materialized/materialized, unmaterialized/materialized, self-append) and was iterated in response to CodeRabbit feedback, all of which is now resolved.
  • The stderr: "" assertion is slightly stricter than REVIEW.md recommends, but was explicitly requested by CodeRabbit and verified green under ASAN debug with bunEnv, so it's not a practical concern.

@robobun

robobun commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

CI status: capture-stack-trace.test.js (the file this PR touches) passes on all lanes in both builds 75782 and 75786. Remaining red/flaky tests are unrelated to this change:

  • test/js/node/http/node-http-server-socket-end-drain.test.ts (pre-existing, macOS ECONNRESET/EPIPE)
  • test/cli/run/no-orphans.test.ts (darwin perl reap timeout)
  • test/js/node/net/node-net.test.ts (mimalloc page-count threshold)
  • assorted flakes that passed on retry (install/migration, terminal, webview, next-pages, etc.)

This PR only adds two guard conditions in errorConstructorFuncAppendStackTrace and one subprocess test; none of the above touch error stack trace handling.

@robobun

robobun commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

Consolidated into #37370, which now also carries the cases from this PR: it returns early for a materialized destination and for source === destination, and the .sourceURL materialization + GC loop from this PR's test is included there (the self-append has its own test under ASAN with Malloc=1). #37370 additionally handles the stackTraceLimit abort, which this branch still hits. Closing.

@robobun robobun closed this Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant