Repository navigation
Closed
Labels
app/pm-stackpm-stack (Pad/Grist) in developing-today/codepm-stack (Pad/Grist) in developing-today/codeeffort/sSmall: expected under 2 hours of workSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)Something isn't working (prefixed form of the classic bug label)priority/highImportant and time-sensitiveImportant and time-sensitivesource/pr-diff-reviewFiled by the pr-diff-review jobFiled by the pr-diff-review jobtask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Description
Finding
In pm-dispatch (pm-stack/dispatch), a failed session launch on the wait:false path is not cleaned up: the queue task is left queued and the tracking issue is never noted. Only the wait:true path cancels the task and notes the issue — the exact behaviour PR #2650's description promises for failed launches generally ("a failed launch cancels the task and notes the issue").
Evidence
- PR feat(pm-stack): pm-dispatch — launch/track OpenCode sessions from GitHub Actions #2650 (commit
19f12cb2e2, MERGED) introduced the service. Its body states: "wait:falseanswers202after the enqueue and finishes the launch asynchronously; a failed launch cancels the task and notes the issue." - Verified on current main (
c4fb599617166d4c705eabeb34442ca179ecb9a6),pm-stack/dispatch/src/server.ts:222-240: the async catch only doespatchTask(task.id, { last_error: "dispatch launch failed: …" }). NocancelTask, no issue comment. - Contrast the same file's
wait:truepath (~line 246+), whose comment states the invariant the async path violates: "Never leave a queued/claimed task behind for a session that did not launch: cancel it and note the failure on the issue."
Why it matters
- The task stays
queued, so a queue worker can claim and execute the packet — while in the partial-failure case (launch got as far ascreateSession+sendPromptand failed afterwards, e.g. at the claim PATCH) a live OpenCode session is also working the same prompt. That is the double-booking the immediate-claim design exists to prevent. - The caller received
202 {status: "launching"}and the tracking issue says nothing further; the failure exists only aslast_erroron a still-queued task row, indistinguishable from a normally-queued dispatch at a glance. - Follow-up PRs fix(pm-dispatch): unwrap the OpenCode v2 {data} response envelope #2652/fix(pm-dispatch): register the dispatch-opencode worker row before claiming #2655/feat(pm-dispatch): record the lane assignment after a launch claim #2658 fixed three other launch-path defects found by deploy smoke tests (envelope, worker FK, lane ledger); none touched this branch.
Acceptance criteria
- The
wait:falseasync failure path mirrors thewait:trueone:cancelTask(task.id, …)is called and, when a tracking issue exists, a comment records that the launch failed and the task was cancelled. - A regression test (stubbed queue/opencode clients, as in the existing
test/suite) covers await:falselaunch failure and asserts the cancellation + issue note. - The README's description of
wait:falsefailure behaviour matches the implementation.
Found by the pr-diff-review job reviewing PR #2650 (batch 2630–2658, 2026-10-30). Deduped: gh issue list --search 'pm-dispatch wait launch cancel' and 'wait:false dispatch' (open + all) returned nothing covering this.
Metadata
Metadata
Assignees
Labels
app/pm-stackpm-stack (Pad/Grist) in developing-today/codepm-stack (Pad/Grist) in developing-today/codeeffort/sSmall: expected under 2 hours of workSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)Something isn't working (prefixed form of the classic bug label)priority/highImportant and time-sensitiveImportant and time-sensitivesource/pr-diff-reviewFiled by the pr-diff-review jobFiled by the pr-diff-review jobtask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Activity
dezren39 commentedon Oct 31, 2026
🤖 Agent note · filed
dezren39 commentedon Oct 31, 2026
🤖 Agent note · triaged — CONFIRMED
c4fb59961, read fresh 2026-10-31): inpm-stack/dispatch/src/server.tsthe wait:false async catch (~L222-240) does onlypatchTask(task.id, { last_error: "dispatch launch failed: …" })— nocancelTask, no issue comment. The wait:true path in the same handler (~L246+) states the invariant ("Never leave a queued/claimed task behind for a session that did not launch: cancel it and note the failure on the issue") and implements cancel + comment + 502.const github = new GitHubClient(...),requireQueue()); the existing test/ suite (auth/config/packet/validate) has no server-level test, so the regression test needs a small stub seam — keep it minimal.3 remaining items
dezren39 commentedon Oct 31, 2026
🤖 Agent note · handed off
dezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up
dezren39 commentedon Oct 31, 2026
🤖 Agent note · filed (cross-reference added on a correction pass)
Relation to the existing launch-pipeline set: #2660 covers the opposite failure on the synchronous path — a comment/label failure after the claim PATCH cancelling a live session's task. #2668 (design epic) scopes its phases to #2664/#2665 (boundary), #2660 (commit point), and #2663 (retryable init). This issue is a fifth, distinct defect not in that set: on the
wait:falsepath, a launch failure before the claim leaves the taskqueuedand claimable, with no cancellation and no note on the tracking issue. If the #2668 staged redesign is implemented, its failure-semantics table should cover this async branch too; until then this issue tracks it directly. (Two sibling issues from this same run, #2902/#2903, WERE duplicates of #2663/#2664 and have been closed as such.)fix(pm-dispatch): post-launch issue annotations are best-effort (#2901,…
fix(pm-dispatch): wait:false launch failure cancels the task and note…
dezren39 commentedon Oct 31, 2026
🤖 Agent note · done