Skip to content

js_printer: wrap cross-module enum inlined as a delete operand when non-finite - #36744

Open
robobun wants to merge 5 commits into
mainfrom
farm/94d2e318/printer-delete-crossmodule-enum
Open

js_printer: wrap cross-module enum inlined as a delete operand when non-finite#36744
robobun wants to merge 5 commits into
mainfrom
farm/94d2e318/printer-delete-crossmodule-enum

Conversation

@robobun

@robobun robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Problem

// enums.ts
export enum E { N = 0/0, I = 1/0 }
// entry.ts
import { E } from './enums';
globalThis.r = delete E.N;
$ bun build ./entry.ts
globalThis.r = delete NaN /* N */;
$ node <(bun build ./entry.ts)
SyntaxError: Delete of an unqualified identifier in strict mode.

Cross-module TS enum inlining happens at print time in the EDot/EIndex arms via try_to_get_imported_enum_value. The source is delete E.N (an EDot), so WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS is set and the (0, ...) re-wrap in the EUnary arm is skipped; the EDot arm then replaces the property access with NaN / Infinity, which are identifier references and therefore a strict-mode delete <id> SyntaxError in the emitted ESM bundle. esbuild has the same bug.

Related but distinct:

Fix

Add ExprFlag::IsDeleteTarget and set it when printing the operand of delete whose parse-time flag is set (so it never reaches compound operands like EIf/EBinary that forward flags to children which are not themselves delete targets). print_inlined_enum wraps in (0, ...) when is_delete_target and the value is a non-finite number. Finite numbers and strings are left as-is (delete 42 / delete "s" are valid strict-mode expressions that already evaluate to true).

delete (0, NaN) evaluates to true, matching the source semantics: enum members are own configurable data properties, so delete E.N returns true. Keeping the property access instead of inlining would require the linker to retain the enum object for this one use; the wrap preserves the return value without that coupling and is consistent with the existing semantic model for enum inlining.

$ bun build ./entry.ts
globalThis.r = delete (0, NaN /* N */);

Verification

$ bun bd test test/bundler/esbuild/ts.test.ts -t EnumCrossModuleInliningDeleteTarget   # 2 new tests, fail on main

Full esbuild/ts.test.ts (59 pass), bundler_edgecase.test.ts (117 pass), bundler_minify.test.ts (42 pass), transpiler.test.js (183 pass), esbuild/default.test.ts (151 pass), esbuild/dce.test.ts (78 pass) unchanged.


[review] gate passed · iteration 1 · 2 files touched

fails on main (without fix)
ASAN without fix: 2 failed, 10 skipped
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/bundler/esbuild/ts.test.ts
bun test v1.4.0 (a05e926a4)

test/bundler/esbuild/ts.test.ts:
(pass) bundler > ts/DeclareConst [539.55ms]
(pass) bundler > ts/DeclareLet [93.69ms]
(pass) bundler > ts/DeclareVar [91.67ms]
(pass) bundler > ts/DeclareClass [89.39ms]
(pass) bundler > ts/DeclareClassFields [441.93ms]
(pass) bundler > ts/DeclareFunction [92.88ms]
(pass) bundler > ts/DeclareNamespace [85.05ms]
(pass) bundler > ts/DeclareEnum [89.57ms]
(pass) bundler > ts/DeclareConstEnum [91.03ms]
(pass) bundler > ts/ConstEnumComments [390.49ms]
(pass) bundler > ts/ImportEmptyNamespace [372.60ms]
(pass) bundler > ts/ImportMissingES6 [96.77ms]
(pass) bundler > ts/ImportMissingUnusedES6 [86.96ms]
(todo) bundler > ts/ExportMissingES6
(pass) bundler > ts/ImportMissingFile [82.19ms]
(pass) bundler > ts/ImportTypeOnlyFile [368.64ms]
(pass) bundler > ts/ExportEquals [408.13ms]
(pass) bundler > ts/ExportNamespace [384.10ms]
(pass) bundler > ts/MinifyEnumExported [179.70ms]
(pass) bundler > ts/MinifyNestedEnum [134.23ms]
(pass) bundler > ts/MinifyNames
... (truncated)

release without fix: 10 skipped
bun test v1.4.0-canary.1 (6f75b3f95)

test/bundler/esbuild/ts.test.ts:
(pass) bundler > ts/DeclareConst [13.85ms]
(pass) bundler > ts/DeclareLet [3.60ms]
(pass) bundler > ts/DeclareVar [3.45ms]
(pass) bundler > ts/DeclareClass [3.21ms]
(pass) bundler > ts/DeclareClassFields [11.24ms]
(pass) bundler > ts/DeclareFunction [3.15ms]
(pass) bundler > ts/DeclareNamespace [2.92ms]
(pass) bundler > ts/DeclareEnum [3.18ms]
(pass) bundler > ts/DeclareConstEnum [3.41ms]
(pass) bundler > ts/ConstEnumComments [11.54ms]
(pass) bundler > ts/ImportEmptyNamespace [10.60ms]
(pass) bundler > ts/ImportMissingES6 [3.88ms]
(pass) bundler > ts/ImportMissingUnusedES6 [4.12ms]
(todo) bundler > ts/ExportMissingES6
(pass) bundler > ts/ImportMissingFile [3.11ms]
(pass) bundler > ts/ImportTypeOnlyFile [10.66ms]
(pass) bundler > ts/ExportEquals [12.56ms]
(pass) bundler > ts/ExportNamespace [11.28ms]
(pass) bundler > ts/MinifyEnumExported [3.78ms]
(pass) bundler > ts/MinifyNestedEnum [5.05ms]
(pass) bundler > ts/MinifyNamespace [3.73ms]
(pass) bundler > ts/MinifyDerivedClass [30.38ms]
(pass) bundler > ts/ImportVsLocalCollisionAllTypes [11.69ms]
(pass) bundler > ts/ImportVsLocalCollisionMixed [9.95
... (truncated)
passes on PR (with fix)
ASAN with fix: 10 skipped
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/bundler/esbuild/ts.test.ts
bun test v1.4.0 (a05e926a4)

test/bundler/esbuild/ts.test.ts:
(pass) bundler > ts/DeclareConst [531.72ms]
(pass) bundler > ts/DeclareLet [109.04ms]
(pass) bundler > ts/DeclareVar [89.93ms]
(pass) bundler > ts/DeclareClass [90.90ms]
(pass) bundler > ts/DeclareClassFields [444.48ms]
(pass) bundler > ts/DeclareFunction [98.77ms]
(pass) bundler > ts/DeclareNamespace [86.16ms]
(pass) bundler > ts/DeclareEnum [87.58ms]
(pass) bundler > ts/DeclareConstEnum [93.80ms]
(pass) bundler > ts/ConstEnumComments [391.13ms]
(pass) bundler > ts/ImportEmptyNamespace [373.64ms]
(pass) bundler > ts/ImportMissingES6 [96.42ms]
(pass) bundler > ts/ImportMissingUnusedES6 [84.47ms]
(todo) bundler > ts/ExportMissingES6
(pass) bundler > ts/ImportMissingFile [81.68ms]
(pass) bundler > ts/ImportTypeOnlyFile [375.97ms]
(pass) bundler > ts/ExportEquals [398.62ms]
(pass) bundler > ts/ExportNamespace [372.37ms]
(pass) bundler > ts/MinifyEnumExported [180.98ms]
(pass) bundler > ts/MinifyNestedEnum [132.42ms]
(pass) bundler > ts/MinifyName
... (truncated)

release with fix: 10 skipped
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 698ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[0/4] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

�[1m�[92m   Compiling�[0m bun_js_printer v0.0.0 (/workspace/bun/src/js_printer)
�[1m�[92m   Compiling�[0m bun_bundler v0.0.0 (/workspace/bun/src/bundler)
�[1m�[92m   Compiling�[0m bun_standalone_graph v0.0.0 (/workspace/bun/src/standalone_graph)
�[1m�[92m   Compiling�[0m bun_transpiler v0.0.0 (/workspace/bun/src/transpiler)
�[1m�[92m   Compiling�[0m bun_bunfig v0.0.0 (/workspace/bun/src/bunfig)
�[1m�[92m   Compiling�[0m bun_install v0.0.0 (/workspace/bun/src/install)
�[1m�[92m   Compiling�[0m bun_jsc v0.0.0 (/workspace/bun/src/jsc)
�[1m�[92m   Compiling�[0m bun_ast_jsc v0.0.0 (/workspace/bun/src/ast_jsc)
�[1m�[92m   Compiling�[0m bun_js_parser_jsc v0.0.0 (/workspace/bun/src/js_parser_jsc)
�[1m�[92m   Compiling�[0m bun_semver_jsc v0.0.0 (/workspace/bun/src/semver_jsc)
�[1m�[92m   Compiling�[0m bun_sys_jsc v0.0.0 (/workspace/bun/src/
... (truncated)
diff hotspot
src/js_printer/lib.rs           | 40 +++++++++++++++++++++++++---
 test/bundler/esbuild/ts.test.ts | 58 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 3 deletions(-)

gate history · 2 passed · 0 rejected · iteration 1

evidence per changed file
file                             reads  edits  tests
src/js_printer/lib.rs               11     13      0
test/bundler/esbuild/ts.test.ts      2      2      0

…-finite

delete E.N across modules (E a TS enum, N = NaN or Infinity) bundled to
'delete NaN' / 'delete Infinity': a strict-mode SyntaxError in the emitted
ESM bundle.

The source is an EDot so WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS
is set and the EUnary '(0, ...)' re-wrap is skipped; the EDot print arm then
replaces the property access with the constant via try_to_get_imported_enum_value.

Thread an IsDeleteTarget ExprFlag from the EUnary delete arm (only when the
parse-time flag is set, so it never reaches compound operands that forward
flags to children) into the EDot/EIndex print arms, and have print_inlined_enum
wrap non-finite numbers in '(0, ...)'. Finite numbers and strings are left as
'delete 42' / 'delete "s"' since those are valid strict-mode expressions.
@github-actions github-actions Bot added the claude label Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The PR adds bundler tests for cross-module enum values in delete expressions. The tests cover non-finite, finite, and string values in regular and minified output.

Changes

Delete-target enum inlining

Layer / File(s) Summary
Safe enum output coverage
test/bundler/esbuild/ts.test.ts
Tests verify that non-finite inlined enum values use (0, value) wrapping, while finite numbers and strings remain directly deletable. Minified output is also covered.

Possibly related PRs

  • oven-sh/bun#36740: Directly tests the printer behavior for inlined enum values in delete expressions.
  • oven-sh/bun#36741: Covers related delete expression semantics through a different code path.
🚥 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 identifies the js_printer fix for non-finite cross-module enum values used as delete operands.
Description check ✅ Passed The description explains the problem, fix, semantics, and verification results, although it uses different headings than the template.

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

@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 — targeted fix for a real bundler correctness bug (delete NaN strict-mode SyntaxError from print-time enum inlining).

What was reviewed:

  • Flag propagation: IsDeleteTarget is only set when WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS is set, so it never reaches compound operands; EDot masks flags before printing e.target (line 3283) and EIndex explicitly removes it, so no leakage into subexpressions.
  • print_inlined_enum wrap: level lowered to Comma inside (0, ...) so print_number doesn't double-paren -Infinity; comment placement stays inside the wrap.
  • Tests exercise both EDot/EIndex, all three non-finite values, finite/string (asserted NOT wrapped), and minified output; run: executes the bundle so a residual delete NaN would SyntaxError and fail.
Extended reasoning...

Overview

Adds ExprFlag::IsDeleteTarget to src/js_printer/lib.rs, threads it from the EUnary delete arm into the EDot/EIndex print arms, and gives print_inlined_enum a new is_delete_target: bool parameter that wraps non-finite numbers in (0, ...). Two new itBundled tests in test/bundler/esbuild/ts.test.ts.

Security risks

None. Bundler output-correctness change; no untrusted-input handling, no allocation, no FFI.

Level of scrutiny

Medium — print_expr is on the hot path for all bundler output, but the added work is a couple of bitset contains/remove calls and a bool parameter. I traced flag lifetime through both arms: in EDot the flag is captured before the early-return inlining path and then stripped by the existing flags &= HasNonOptionalChainParent | ForbidCall mask before e.target is printed; in EIndex it is explicitly removed before e.target/e.index are printed. The gating on the parse-time WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS flag guarantees the operand was an identifier/property-access in source, so the flag cannot land on an EIf/EBinary that would forward it to a non-delete-target child. Optional-chain accesses (delete E?.N) skip the inlining branch entirely (e.optional_chain.is_none()), so no interaction there.

The wrap itself mirrors the existing (0, ...) pattern already used in the EUnary arm (b"(0," + print_space() + inner at Level::Comma + b")"). Placing the closing paren after the /* name */ comment matches the whitespace-minified assertion (delete(0,NaN) — comment suppressed under minify_whitespace).

Other factors

The PR description is unusually precise about why #36740 (guard on the unset-flag path) and #36734 (visitor-time delete_target for same-module EInlinedEnum) do not cover this print-time EImportIdentifier path — I verified that reasoning against the code. The test matrix hits every branch of the wrap predicate (NaN / +Inf / -Inf wrapped; finite 42 and string "s" explicitly asserted unwrapped) across both E.N and E["N"], and the run: stdout check would fail on the unfixed build via SyntaxError, so the tests are non-vacuous. The choice to wrap rather than suppress inlining is justified (semantics preserved: delete (0, NaN)true, matching delete on a configurable enum member) and avoids forcing the linker to retain the enum object.

Comment thread src/js_printer/lib.rs Outdated
Comment thread src/js_printer/lib.rs Outdated
Comment thread src/js_printer/lib.rs Outdated
Comment thread src/js_printer/lib.rs Outdated

@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: 1

🤖 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/bundler/esbuild/ts.test.ts`:
- Around line 2239-2243: Shorten or remove the paragraph comment above the
cross-module enum inlining test. Keep only a concise statement of the
non-obvious behavior being tested, relying on the test name and assertions for
the specific NaN/Infinity cases; do not describe printer control flow or
implementation details.
🪄 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: 7697f0af-afca-4062-8358-69777eb80943

📥 Commits

Reviewing files that changed from the base of the PR and between f91d5c9 and 5aa6d6f.

📒 Files selected for processing (2)
  • src/js_printer/lib.rs
  • test/bundler/esbuild/ts.test.ts

Comment thread test/bundler/esbuild/ts.test.ts Outdated
Comment thread src/js_printer/lib.rs Outdated
Comment thread src/js_printer/lib.rs Outdated

@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):

  • 🟡 src/js_printer/lib.rs:4033-4040 — The same WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS → strict-mode delete <id> explanation is repeated across the ExprFlag::IsDeleteTarget doc comment (1245-1249), this 8-line block, and the 5-line block in print_inlined_enum (6196-6200) — the comment-cop bot flagged all of them. Consider keeping the shared mechanism once on the enum-variant doc comment and trimming each call site to its unique bit: here, just the one-liner about gating on the parse-time flag so it never reaches EIf/EBinary children; in print_inlined_enum, just the delete <value>true semantics.

    Extended reasoning...

    What

    This PR adds three multi-line comment blocks that each restate the same core invariant:

    • ExprFlag::IsDeleteTarget doc comment (lib.rs:1245-1249): the operand of a delete whose source form was an identifier/property access; a print-time rewrite that surfaces a bare identifier (cross-module enum inlining to NaN/Infinity) must keep it a value.
    • EUnary arm (lib.rs:4033-4040): the operand was a property access in source, so the (0, ...) re-wrap above is skipped; cross-module enum inlining can still replace it with NaN/Infinity (a strict-mode delete <id> SyntaxError); tell the operand it's the delete target so the inline path can wrap itself.
    • print_inlined_enum (lib.rs:6196-6200): delete E.N sets WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS, so the EUnary arm does not re-wrap; inlining a non-finite number would print delete NaN — a strict-mode SyntaxError; wrap in (0, ...).

    All three narrate the same causal chain: parse-time flag set → EUnary skips the re-wrap → print-time enum inlining emits NaN/Infinity → strict-mode delete <id> SyntaxError. The repo's github-actions comment-cop bot flagged every one of these locations on the PR timeline with the CLAUDE.md rule-13 quote ("If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code").

    Why it applies

    REVIEW.md's comment rule is explicit: "Comments carry only durable non-obvious content… No narrating what the code does, no bug history — that belongs in the PR description." CLAUDE.md rule 14 adds: "Is this information the next Claude would spend multiple tool calls trying to understand? If the answer isn't clearly yes, the code comment is noise — delete it." And src/CLAUDE.md says outright: "Avoid adding comments where not necessary."

    The invariant itself is non-obvious and worth documenting once — a reader landing on print_inlined_enum with no context would not immediately guess why is_delete_target && !n.is_finite() triggers a (0, ...) wrap. But once the ExprFlag::IsDeleteTarget doc comment states the contract ("a print-time rewrite that would surface a bare identifier here must keep it a value, not a Reference"), the call sites are just honoring that contract, and re-explaining the whole WAS_ORIGINALLY_...EUnary re-wrap-skip → SyntaxError chain at each site is narration the PR description already covers in full.

    Step-by-step

    1. A reader hits value_flags.insert(ExprFlag::IsDeleteTarget) at line 4041 and wants to know what the flag means.
    2. They jump-to-definition → land on the enum variant at 1245-1249, which already says: direct operand of a delete whose source was an identifier/property access; print-time rewrites that would surface a bare identifier (e.g. cross-module enum inlining to NaN/Infinity) must keep it a value.
    3. That's the whole mechanism. The 8-line block at 4033-4040 re-tells the same story, adding only one non-derivable fact: gating on the parse-time flag keeps this from reaching compound operands (EIf/EBinary) that forward flags to children which are not themselves delete targets.
    4. Similarly at 6196-6200: the only fact not already on the enum doc is the semantics justification — delete <value> evaluates to true, matching the source semantics (enum members are configurable).

    Suggested trim

    Keep the ExprFlag::IsDeleteTarget doc comment as the canonical explanation, then:

    • 4033-4040 → one line: // Gate on the parse-time flag so IsDeleteTarget never reaches EIf/EBinary children via forwarded flags.
    • 6196-6200 → one line: // delete (0, NaN) evaluates to true, matching delete E.N on a configurable member.
    • The 2-line comment at 3316-3317 (EIndex) is already terse and site-specific; it can stay.

    Impact

    None on behavior — this is comment hygiene only. It's flagged as a nit because the code is correct and the explanation is useful; it's just stated three times where once (plus site-specific one-liners) would do, and the repo's own automation already called it out.

@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 — targeted printer fix for a strict-mode delete <identifier> SyntaxError from cross-module enum inlining.

What was reviewed:

  • Flag propagation: IsDeleteTarget is only set when the parse-time WAS_ORIGINALLY_DELETE_OF_IDENTIFIER_OR_PROPERTY_ACCESS flag is set, so it never reaches compound operands; EDot clears it via the flags &= ... mask before recursing into the target, and EIndex removes it explicitly.
  • Both call sites of print_inlined_enum updated; wrap emits (0, X /* name */) with level = Comma and closes after the comment, matching the asserted output in both normal and minified modes.
  • Tests cover EDot and EIndex paths, all three non-finite values, finite/string (left unwrapped), plus a run assertion so the bundle actually executes.
Extended reasoning...

Overview

Fixes a bundler codegen bug where cross-module TS enum inlining at print time emits delete NaN / delete Infinity — a strict-mode SyntaxError in the ESM output. Changes are confined to src/js_printer/lib.rs (~35 lines: one new ExprFlag variant, threading it from the EUnary delete arm into the EDot/EIndex arms, and a small wrap in print_inlined_enum) plus two new itBundled tests in test/bundler/esbuild/ts.test.ts.

Security risks

None. Pure print-time output shaping; no untrusted input parsing, no allocations, no FFI.

Level of scrutiny

Moderate — bundler output correctness matters, but this is a narrow, well-understood edge case (delete on an inlined non-finite enum member). The mechanism is precise: IsDeleteTarget is set only when op == UnDelete and the parse-time flag confirms the original operand was a property access, so the operand at print time is exactly the EDot/EIndex node — the flag cannot leak to unrelated children. In EDot the subsequent flags &= HasNonOptionalChainParent | ForbidCall mask clears it before recursing into the target; in EIndex it's removed explicitly before both the target and index are printed. The wrap uses Level::Comma inside the parens, which is correct for (0, X).

Other factors

  • Only two callers of print_inlined_enum exist and both are updated.
  • Tests exercise both the EDot (E.N) and EIndex (E["N"]) inlining paths, all non-finite values (NaN, ±Infinity), and confirm finite numbers / strings are left unwrapped (delete 42 / delete "s" are valid). The minified variant checks whitespace-free output. Both tests run the bundle and assert [true,...], so a SyntaxError would fail loudly.
  • All prior bot comments (comment-cop, CodeRabbit) were about comment length and are resolved; the one remaining source comment is a single line stating the invariant.
  • The PR description explains why the sibling fixes in #36740 (unset-flag path) and #36734 (visit-time EInlinedEnum) don't cover this print-time EImportIdentifier path — the reasoning checks out against the code.

@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

Diff is ready: the two new EnumCrossModuleInliningDeleteTarget tests fail on main and pass with the fix; full esbuild/ts.test.ts, bundler_edgecase.test.ts, bundler_minify.test.ts, transpiler.test.js, esbuild/default.test.ts, esbuild/dce.test.ts unchanged locally. Format / Lint JavaScript / Source lints all green.

Build 87497 (final): all build-cpp/build-bun jobs passed on every platform; 184 test jobs passed. test/bundler/esbuild/ts.test.ts (where the new tests live) is green on every lane that ran. Remaining red is unrelated to this diff:

  • pre-existing: AWS EC2 rejected the x64-asan / windows-aarch64 test-bun instance requests ("requested configuration is currently not supported"), so those shards were canceled; test/js/web/timers/setInterval.test.js memory-leak timeout on x64-asan also fails on main.
  • flaky (passed alone on retry): request-clone-leak, 21907, test-error-code-done-callback, tty-reopen-after-stdin-eof, multi-run, node-module-module, fetch-tls-cert, zlib/leak.

Earlier builds 87409/87436 had every job expire with no agents available.

@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 10:19 PM PT - Aug 1st, 2026

@robobun, your commit a05e926 has 2 failures in Build #87497 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 36744

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

bun-36744 --bun

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