You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cc's MCP debug logger writes nothing under perry — even when its catch handler demonstrably runs; and exec/execFile callback order is inverted #9500
Two secondary findings from the #9485 investigation (PR #9498).
1. The MCP debug log tree is never created
Node writes 6 lines to ~/.cache/claude-cli-nodejs/<key>/mcp-logs-*/…jsonl on a failed connect. Perry writes nothing — no .cache tree at all — even though the bundle's OL catch demonstrably runs (i8(...)/yz(...) execute; the connect returns type:"failed", not the outer BX5 catch).
#9485 assumed the missing logs were purely downstream of never connecting. That is now disproven: the connect fails, the error path runs, and the logger is still silent. Most likely an async-write/exit-flush gap adjacent to the #9421 family (merged PR #9491 fixed appendFile error-swallowing; this logger may use a different write shape — createWriteStream is still synchronous-under-the-hood per #9493, and a failed dir-creation on this path would now throw post-#9491 rather than vanish — re-test on a post-#9491 build first, the behaviour may have changed).
Why it matters: this is why #9485 had zero diagnostics to start from. Debug logging that dies silently multiplies the cost of every other bug.
2. cp.exec / cp.execFile callbacks fire in the opposite order vs node
perry: exec→execFile; node: execFile→exec (same script, same commands). Ordering-sensitive test suites and promisified-parallel patterns can see it. Small, but it is a scheduling-semantics divergence in freshly-unlocked territory (PR #9498 made these callable as cp.exec(...) at all), so it was previously unreachable.
3. Drift-capable duplicate knowledge (maintenance, not behaviour)
is_cjs_style_native_default_import, cjs_default_namespace_name, cjs_default_base_module, and the dispatch router's table were four hand-maintained copies of the same module-name knowledge; #9498 collapsed the router's copy onto the canonical one with ratchet tests. The other three remain and can drift exactly the way the router did. A follow-up that derives them from one source kills the recurring-bug factory.
Significance upgrade from the clean 15-case re-run (layer-1-only cc binary, PR #9498 in): the missing MCP log tree is not a diagnostics nicety — it is the only remaining divergence for the whole mcp add family.
B11_mcp_list_cfg's detail shows stdout already byte-identical to node after the spawn fix, with HOME-PATHS-ONLY-IN-NODE: ['.cache/claude-cli-nodejs/<CWDKEY>/mcp-logs-*'] as the sole flag. The same pattern holds across the add-family cases (~12 of the 15). The connect-path residual (#9499) bites only the self-server cases (E20/E21/E22), which still carry a stdout diff.
So the expected suite arithmetic: #9499 + this issue together clear all 15; this issue alone is worth ~12 cases. Whoever picks it up should also note the #9485 thread's finding that the logger stays silent even when the error path demonstrably runs — and re-test on a post-#9491 build first, since appendFile error-swallowing (a prime suspect for a silently-failing logger) was fixed there.
exec/execFile order is a same-turn delivery artefact, not a rule. Node fires whichever of two instant children was submitted second first; for three identical batches in one process it gives C B A then B A C. The only order node guarantees — completion order — perry matches, and that is what test_gap_9500_exec_callback_completion_order.ts pins. The reactor is unchanged.
The module-name knowledge was five copies, not four (the HIR had two that already disagreed). They are now one table in perry-dispatch, with every consumer derived from it.
With the logs readable, three further divergences fell out and are filed with fixtures: #9535 (child lifecycle delivered before the continuation that awaited 'spawn' → the SDK's Not connected), #9536 (fetch(URL instance) → Invalid URL), #9537 (null-byte validation missing on the require() path). Those plus #9499 are what remains of the 15.
Activity
proggeramlug commentedon Sep 2, 2026
Significance upgrade from the clean 15-case re-run (layer-1-only cc binary, PR #9498 in): the missing MCP log tree is not a diagnostics nicety — it is the only remaining divergence for the whole
mcp addfamily.B11_mcp_list_cfg's detail shows stdout already byte-identical to node after the spawn fix, withHOME-PATHS-ONLY-IN-NODE: ['.cache/claude-cli-nodejs/<CWDKEY>/mcp-logs-*']as the sole flag. The same pattern holds across the add-family cases (~12 of the 15). The connect-path residual (#9499) bites only the self-server cases (E20/E21/E22), which still carry a stdout diff.So the expected suite arithmetic: #9499 + this issue together clear all 15; this issue alone is worth ~12 cases. Whoever picks it up should also note the #9485 thread's finding that the logger stays silent even when the error path demonstrably runs — and re-test on a post-#9491 build first, since
appendFileerror-swallowing (a prime suspect for a silently-failing logger) was fixed there.changelog: fragment for PerryTS#9531 (PerryTS#9500)
proggeramlug commentedon Sep 2, 2026
PR #9531 covers all three findings; the short version of what the measurements said:
straceon the pre-fix(fs): appendFile must report failure, not resolve; writeFileSync must throw; mode must reach open(2) (#9421) #9491 cc binary shows both engines reaching the sameopenat(…/mcp-logs-alpha/….jsonl, O_APPEND) = ENOENT; node follows with the recursivemkdirchain and a successful retry, perry with nothing —appendFileSyncreturned success, so thecatch { mkdirSync; appendFileSync }arm that is the only code creating the tree never ran. The flush itself always happened (the 1 s timer). cc compiled from post-fix(fs): appendFile must report failure, not resolve; writeFileSync must throw; mode must reach open(2) (#9421) #9491 main writes the logs in all 15 harness cases; the shape is pinned bytest_gap_9500_mcp_debug_logger_shape.ts, which fails on a pre-fix(fs): appendFile must report failure, not resolve; writeFileSync must throw; mode must reach open(2) (#9421) #9491 tree.C B AthenB A C. The only order node guarantees — completion order — perry matches, and that is whattest_gap_9500_exec_callback_completion_order.tspins. The reactor is unchanged.perry-dispatch, with every consumer derived from it.With the logs readable, three further divergences fell out and are filed with fixtures: #9535 (child lifecycle delivered before the continuation that awaited
'spawn'→ the SDK'sNot connected), #9536 (fetch(URL instance)→Invalid URL), #9537 (null-byte validation missing on therequire()path). Those plus #9499 are what remains of the 15.refactor(cjs-default): one shared table for the `<mod>.default` modul…
test(gap): pin claude-code's MCP debug logger write shape (#9500)
test(gap): exec/execFile callbacks fire in completion order (#9500 pa…
changelog: fragment for #9531 (#9500)