From the 196-case cc stress re-run (main+#9479). Two spellings of one gap:
cc doctor (B01/B02, and B62 setup-token): ink's raw-mode error renders err.stack. Node prints ten real frames; perry prints one placeholder:
node : - handleSetRawMode (file://<CLI>:574:5473)
- (file://<CLI>:601:4834)
- S0 (file://<CLI>:551:63170)
… (10 frames)
perry: - at <anonymous>
commander's parse error (C24, --max-budget-usd abc): node prints the source excerpt, code frame, message and stack (14,573 bytes of stderr); perry prints 120 bytes — the bare message. E30_corrupt_config_mcp_list's 885-vs-1024-byte stderr diff is likely the same family (verify before assuming).
Why this matters beyond parity
Stack traces are how everything else gets debugged. Every divergence investigation in this campaign that touched cc had to work around frameless errors — the #9417 hunt needed gdb + a symbolized build precisely because a JS-level stack said <anonymous>.
Relation to existing work
#9432/#9410 added .stack existence for Error subclasses (a frame captured at construction, name: message head formatted on read). This issue is about frame content: the capture produces no usable frames for ordinary throws on real call stacks. #9468 (method source text) is adjacent but separate — frames need function names and positions, not source text.
Perry compiles to native, so JS-frame names/positions need either the existing symbolication tables (the PERRY_KEEP_SYMBOLS path proves names exist) wired into the stack captor, or a side table mapping return addresses → function display names. Scope the cost before building: cc-sized binaries have 141k functions; the doctor case only needs names+offsets, not columns.
Verification bar
A fixture comparing new Error().stack shape (frame count > 1, function names present) for: a plain function chain, a method call, an async function, a class constructor, and a callback through a builtin (arr.map(fn)) — byte-comparing against node is NOT the bar here (positions will differ legitimately); assert structure. Plus the cc-level check: doctor's stderr frame count.
Cases: B01, B02, B62, C24 (+E30 to verify) of the stress suite — /root/claude-ccstress/report_detail.txt.
From the 196-case cc stress re-run (main+#9479). Two spellings of one gap:
cc
doctor(B01/B02, and B62setup-token): ink's raw-mode error renderserr.stack. Node prints ten real frames; perry prints one placeholder:commander's parse error (C24,
--max-budget-usd abc): node prints the source excerpt, code frame, message and stack (14,573 bytes of stderr); perry prints 120 bytes — the bare message.E30_corrupt_config_mcp_list's 885-vs-1024-byte stderr diff is likely the same family (verify before assuming).Why this matters beyond parity
Stack traces are how everything else gets debugged. Every divergence investigation in this campaign that touched cc had to work around frameless errors — the #9417 hunt needed gdb + a symbolized build precisely because a JS-level stack said
<anonymous>.Relation to existing work
#9432/#9410 added
.stackexistence for Error subclasses (a frame captured at construction,name: messagehead formatted on read). This issue is about frame content: the capture produces no usable frames for ordinary throws on real call stacks. #9468 (method source text) is adjacent but separate — frames need function names and positions, not source text.Perry compiles to native, so JS-frame names/positions need either the existing symbolication tables (the
PERRY_KEEP_SYMBOLSpath proves names exist) wired into the stack captor, or a side table mapping return addresses → function display names. Scope the cost before building: cc-sized binaries have 141k functions; the doctor case only needs names+offsets, not columns.Verification bar
A fixture comparing
new Error().stackshape (frame count > 1, function names present) for: a plain function chain, a method call, an async function, a class constructor, and a callback through a builtin (arr.map(fn)) — byte-comparing against node is NOT the bar here (positions will differ legitimately); assert structure. Plus the cc-level check:doctor's stderr frame count.Cases: B01, B02, B62, C24 (+E30 to verify) of the stress suite —
/root/claude-ccstress/report_detail.txt.