buzz-acp: channel wedges permanently when a session's agent child dies (-32603 retried into the same dead session until dead-letter)
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
Research direction
Start in crates/buzz-acp/pool.rs at run_prompt_task and trace the AgentError handling, session cache lookup, and existing invalidate-and-recreate path used for max_turns_per_session rotation. Treat AgentError code -32603 as invalidating the session, then verify that a retry creates a fresh session instead of repeatedly prompting the dead one.
Written by the indexing model from the issue text.
Description
Draft: buzz-acp: channel wedges permanently when a session's agent child dies (-32603 retried into the same dead session until dead-letter)
Component: buzz-acp (crates/buzz-acp), observed at desktop-v0.5.3
Severity: channel outage until process restart, silent message loss
Summary
If a session's underlying agent child dies out-of-band (in our case: an operator killed claude session processes), the next session/prompt returns JSON-RPC -32603 "Internal error". buzz-acp classifies every AgentError as "application error — pipe intact", returns the agent to the pool, and crucially leaves SessionState.sessions[channel_id] pointing at the dead session:
pool.rsrun_prompt_taskerror arm:if !matches!(e, AcpError::AgentError { .. }) { agent.state.invalidate(&source); }— the healthy-session exemption also covers dead sessions.- The requeued batch (
MAX_RETRIES = 10, exponential backoff) re-entersrun_prompt_task, hits the session cache (sessions.get(cid)), and re-prompts the same dead session every attempt until the batch dead-letters. - There is no per-session liveness probe and no
session/load, so nothing ever heals the map short of restarting the whole process.
Real-world impact for us: two channels deaf for ~4 hours, 52 owner events dead-lettered.
Suggested fix (minimal)
Treat -32603 as session-invalidating: matches!(e, AcpError::AgentError { code, .. } if *code == -32603) → agent.state.invalidate(&source). The already-existing requeue path then misses the session cache and create_session_and_apply_model builds a fresh session on the next attempt. False positives are cheap (one extra session/new); false negatives wedge the channel. The proactive max_turns_per_session rotation already proves the invalidate-and-recreate idiom.
We are running this patch locally and can PR it if you'd take it.
- Dominant language
- Rust
- Stars
- 33.7k
- Forks
- 4.4k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 239
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from block/buzz
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
workflow_sink's mention parser never masks code regions — @name inside a code span wakes the agent Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 Half a day Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100