Files
cc-connect/agent
Claude 5f27718a6b fix(core): prevent race condition during session cleanup
Two race conditions fixed:

1. cleanupInteractiveState timing (main issue):
   - Previously: state was deleted from interactiveStates map BEFORE
     closeAgentSessionWithTimeout was called synchronously
   - Problem: during the blocking close (up to 130s for Stop hooks),
     the map was empty but agent session was still shutting down
   - Result: concurrent requests saw conflicting state - some got
     "No execution in progress" while others saw blocking behavior
   - Fix: delete state from map AFTER closeAgentSessionWithTimeout
     completes, with re-check to avoid deleting replaced states

2. readLoop defer leak (secondary issue):
   - Previously: defer had early return on ctx.Done() that skipped
     closing cs.events and cs.done channels
   - Problem: if Close() timed out and called cancel(), the defer
     returned early without closing channels
   - Result: Close() waits forever on cs.done at line 633
   - Fix: remove early return from defer, always close channels

Root cause identified in issue #595:
- Session cleanup during /stop in cleanup window created conflicting
  replies ("Previous request still processing" vs "No execution in progress")
- MCP servers and Stop hook subprocesses with stdio:inherit could
  block scanner.Scan() indefinitely, preventing defer cleanup

Test plan:
- go build ./... passes
- go vet ./... passes
- go test ./... passes

Fixes #595

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 08:11:28 +00:00
..