Skip to content

Non-worker draft discard: unobserved closeSession rejection can exit the process; pendingAttaches window discards a draft mid-attach #1922

Description

@snimu

Two latent bugs in the non-worker daemon draft-discard path (packages/coding-agent/src/modes/daemon/daemon-mode.ts), found by Macroscope while reviewing #1897 but pre-dating that stack (both verified present on main). They only bite when AgentDaemon runs with options.worker unset (isDiscardableDraft returns false in worker mode), i.e. in-process/SDK-style sessions.

  1. Unhandled rejection on draft discard can kill the process. Both discard sites call void this.closeSession(state, "killed") (broadcastToSession, and the queueMicrotask in detachClientFromSession). The daemon installs an unhandledRejection handler that exits the process, so a rejection during best-effort teardown terminates it instead of failing the discard. Fix: observe the rejection (.catch + log), matching other best-effort teardown calls in the file.

  2. isDiscardableDraft ignores pendingAttaches. attach increments state.pendingAttaches (daemon-mode.ts:3698) before the client joins state.clients, but isDiscardableDraft checks only clients.size. A turn_end/compaction_end/bash_end in that window discards a draft that has an in-flight attach, and the attach then fails its liveness check. Fix: return false when state.pendingAttaches > 0.

Both fixes are one-liners plus a regression test each; kept out of #1897 because the behavior pre-exists the roster stack.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions