inspect: handle circular references in JSX elements#29583
Conversation
Bun.inspect() on a React element whose key, props, or children referenced itself would recurse until the stack overflowed. The .JSX tag was missing from canHaveCircularReferences(), so the visited-set check and stack guard in printAs were skipped.
|
Updated 5:05 AM PT - Apr 22nd, 2026
❌ @robobun, your commit 3041c69 has 2 failures in
🧪 To try this PR locally: bunx bun-pr 29583That installs a local version of the PR into your bun-29583 --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 changes extend the circular-reference detection mechanism to include JSX values and add test coverage verifying that self-referential React-element-like objects are properly rendered with circular-reference markers. Changes
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
LGTM — minimal one-line fix adding .JSX to the circular-reference guard, with regression tests.
Extended reasoning...
Overview
This PR adds .JSX to the canHaveCircularReferences() switch in src/bun.js/ConsoleObject.zig so that the visited-set / stack-safety guard at the top of printAs runs for React elements. It also adds a regression test in test/js/bun/util/inspect.test.js covering circular key, prop value, and children. Total production change is one token added to an existing switch arm.
Security risks
None. This is purely a console/inspect formatting code path with no auth, crypto, I/O, or untrusted-input parsing implications. The change strictly adds a defensive guard (cycle detection + stack check) that was already applied to every other recursive container tag.
Level of scrutiny
Low. The fix is mechanical and follows the established pattern exactly: .Function, .Array, .Object, .Map, .Set, .Error, .Class, .Event already participate in the same guard, and .JSX is the obvious missing member since its formatter recurses into arbitrary user values (key/props/children). I verified at ConsoleObject.zig:2094-2123 that the guard inserts the value into this.map, prints [Circular] on revisit, and removes it on exit via defer, so adding .JSX simply opts that branch into the same well-tested machinery.
Other factors
The PR was generated from a Fuzzilli crash repro and includes three targeted assertions that exercise each recursion entry point in the .JSX branch. No bugs were flagged by the bug-hunting system, there are no outstanding reviewer comments, and the change cannot regress non-circular JSX output (the guard is a no-op on first visit).
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
|
Duplicate of #29170, which already covers this fix plus the same bug in |
What does this PR do?
Bun.inspect()on a React element whosekey,props, orchildrenreferenced itself (directly or indirectly) would recurse until the stack overflowed and the process segfaulted.The
.JSXtag was missing fromcanHaveCircularReferences(), so the visited-set check and stack guard at the top ofprintAswere skipped for React elements. Formatting thekey(or any prop/child) would re-enter the.JSXbranch with the same value forever.Repro
Now prints
<div key=[Circular] />.How did you verify your code works?
test/js/bun/util/inspect.test.jscovering circularkey, prop value, andchildrenFound by Fuzzilli (fingerprint
6e718886f45af13a).