Fix crash in Bun.plugin when target coercion throws#31162
Conversation
When the `target` option passed to Bun.plugin() had a Symbol.toPrimitive or toString that threw (or returned a non-primitive), toStringOrNull() would set a pending exception and return null. The code then fell through to constructEmptyObject() and call() with the exception still pending, triggering an assertion failure in debug builds. Add RETURN_IF_EXCEPTION checks after the string coercion so the exception is properly propagated to the caller.
|
Updated 9:03 PM PT - May 20th, 2026
❌ @robobun, your commit 6ddac7b has 5 failures in
🧪 To try this PR locally: bunx bun-pr 31162That installs a local version of the PR into your bun-31162 --bun |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe PR improves exception handling for the Bun plugin's ChangesPlugin target validation exception handling
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
|
Duplicate of #31017 (same fix, already green). |
There was a problem hiding this comment.
LGTM — straightforward exception-check fix following the established RETURN_IF_EXCEPTION pattern, with tests.
Extended reasoning...
Overview
This PR adds two RETURN_IF_EXCEPTION checks in setupBunPlugin() (src/jsc/bindings/BunPlugin.cpp) after coercing the target option to a string. When toStringOrNull() throws (e.g., Symbol.toPrimitive throws or returns a non-primitive) it returns nullptr with a pending exception; the old code fell through to constructEmptyObject() / call() and tripped a debug assertion. The inner check after ->value(globalObject) covers rope-resolution / OOM throws, and the outer check covers the nullptr-with-pending-exception path. Two regression tests are added to plugins.test.ts.
Security risks
None. This only adds early-return guards on an already-existing throw scope in input-validation code. No new attack surface, no auth/crypto/permissions involved.
Level of scrutiny
Low. The change is two lines of boilerplate that match the idiom used dozens of times elsewhere in this same file (and throughout the JSC bindings). It is a fuzzer-found debug-assert fix with a clear repro and a precise, minimal patch.
Other factors
- Bug hunting system found no issues.
- New tests directly exercise both the throwing-
toPrimitiveand throwing-toStringpaths, plus the "toPrimitive returns object" TypeError case. - No CODEOWNERS entry covers this path.
- No outstanding reviewer comments.
When the
targetoption passed toBun.plugin()has aSymbol.toPrimitiveortoStringthat throws (or returns a non-primitive),toStringOrNull()sets a pending exception and returnsnullptr. The code then fell through toconstructEmptyObject()andcall()with the exception still pending, triggering an assertion failure in debug builds:Repro:
Fix: add
RETURN_IF_EXCEPTIONafter coercingtargetto a string so the exception is propagated to the caller as a normal JS error.Fuzzer fingerprint:
e19793ee445baafd