block / block/buzz

buzz-acp: channel wedges permanently when a session's agent child dies (-32603 retried into the same dead session until dead-letter)

Open
#4,369 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

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.rs` `run_prompt_task` error 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-enters `run_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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.