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
serve drops calls it already read when input closes in the same burst #190
When a client writes its requests and closes stdin in the same burst, baley serve answers initialize and tools/list, then exits 0 without answering the tools/call requests it already read. Not even the server-overloaded answer a closed queue gives. Found while verifying T4 (#189), reproduced on main at da53839.
Repro: a fresh BALEY_HOME at mode 0700, CLAUDE_PROJECT_DIR pointing at an empty directory, and in.jsonl holding a 2025-11-25 initialize from claude-code, notifications/initialized, tools/list (id 2) and eight tools/call of baley_version (ids 3 to 10).
baley serve < in.jsonl # ids 1 and 2 answered, exit 0 (4 of 5 runs, the fifth also answered id 8)
(cat in.jsonl; sleep 0.005) | baley serve # all 10 answered
Either way stderr carries the usual exit checkpoint complete line, so nothing tells the client calls were dropped. With input held open, ids 3 to 7 and 9 answer ok and 8 and 10 answer server-overloaded, which is the queue doing its job, one running and four waiting.
Likely cause, from reading the code, not proven yet. rmcp reads the frames, spawns a task per call, then sees end of input and would wait up to 5 s to send the answers still in flight (rmcp 3.5.0, src/service.rs:1755-1800). Baley's run() sees input end at the same moment, closes admission and the worker, and finds the queue empty because those calls haven't reached admission yet (crates/baley/src/mcp/serve.rs:160-200). So the drain is over at once, run() returns, and run_serve shuts the runtime down with a zero timeout (crates/baley/src/main.rs:191-194), which drops rmcp's drain mid-flight.
Claude Code closes a stdio server's input only when the session ends, so a live session shouldn't hit this, and a dropped call records and applies nothing because it never reached the queue. A scripted client, a test harness or any host that pipes its requests hits it every time. T12 runs the live shutdown checks, and under the Build 3 plan a defect it confirms is fixed in its own bug PR, with a unit test on the decision that owns it. The fix: the drain covers calls rmcp has already read, inside the same ten-second bound, and every call that was read gets an answer, server-overloaded at worst.
T12 merged in #236 without reproducing this live: no call was in flight inside the server at exit, so the burst check stayed unverified. T17 owns it now. It runs the installed server live, and a defect it confirms is fixed in its own bug pull request, with a unit test on the decision that owns it.
Activity
crenshawdev commentedon Oct 9, 2026
T12 merged in #236 without reproducing this live: no call was in flight inside the server at exit, so the burst check stayed unverified. T17 owns it now. It runs the installed server live, and a defect it confirms is fixed in its own bug pull request, with a unit test on the decision that owns it.