Skip to content

fix(pm-dispatch): failed launches leave orphan tracking issues open (66 open, #3499–#4899) #4917

Closed

Description

@dezren39

Problem

A dispatch whose launch fails after the tracking issue is created leaves that issue open, empty and uncommented — an orphan. There are 66 such issues open right now, all titled with the literal test prompt do the thing:

#3499 #3500 #3501 #3502 #3503 #3504 #3863 #3864 #4029 #4030 #4037 #4038 #4039 #4040 #4042 #4043 #4228 #4229 #4237 #4239 #4244 #4245 #4247 #4248 #4343 #4344 #4348 #4349 #4531 #4532 #4859 #4860 #4892 #4893 #4894 #4895 #4896 #4897 #4898 #4899 (and older)

Every one has body exactly:

do the thing

---
Launched by pm-dispatch for developing-today/code. Queue task and OpenCode session ids follow in a comment below.

and zero comments until the coverage loop-back pass of 2026-11-03 began adding its own reviewed notes.

Evidence / root cause

pm-stack/dispatch/src/server.ts handleSessions:

  1. step 1 creates the tracking issue (maybeCreateIssue, line ~199);
  2. step 2 enqueues the task (enqueueDispatchTask); its failure path returns 502 without touching the issue (server.ts ~482–493);
  3. step 3 creates the session; a session failure likewise returns with the issue left behind.

The comment that would have carried "Queue task #… OpenCode session #…" is only posted after the launch succeeds (annotateLaunch, ~500+). So exactly the failure shape above — issue created, no comment ever — is the signature of a launch that died between issue creation and the first annotation. That is the 66-issue pattern.

The prompt is the literal test string from pm-stack/dispatch/test/validate.test.ts / test/server.test.ts (prompt: "do the thing"), so these are manual/test dispatches fired against the production repo (developing-today/code) with a deliberately meaningless prompt — and the successful ones among them are where the orphans come from when only part of the launch path worked.

Design #2668 states the principle "validate the whole request at the boundary, one commit point, nothing after it can fail the launch"; the tracking issue is created before the commit point and has no compensating action, which is the gap.

Scoped fix

  1. Compensation: when the launch fails after maybeCreateIssue succeeded (enqueue 502 path, session creation failure), post a short failure comment on the issue and close it as not planned — or move issue creation after the enqueue/session commit point, keeping the issue as the record only once the launch is real.
  2. Cleanup: close the existing 66 orphans (they carry no spec), each with a one-line reason pointing here.
  3. Guard: optionally refuse POST /v1/sessions with the test prompt against a production repo, or keep test dispatches on a scratch repo, so the smoke path cannot file issues in developing-today/code.

For other triage lanes

Any further do the thing issue is the same artifact: triage it by closing it with a pointer here. Do not open a second fix issue for this class.

Found by triage of #4898 (queue task 7881, repo-health-code-pilot).

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    queue/queuedHas a queued task in the Supabase agent queue
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  2. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    state: picked-up
    task 8030 (small_fix, lane code-j, direct) claimed 2026-11-03T13:52Z. Issue #4917 revalidated OPEN, no hard-stop labels. Plan: laptop worktree from ~/git/code main, compensation in pm-stack/dispatch/src/server.ts (comment + close as not planned on enqueue/session failure after issue creation), targeted test, orphan cleanup with pointer here, PR + merge under standing criteria.

  3. added a commit that references this issue on Nov 3, 2026
  4. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    state: done
    task 8030 (small_fix, lane code-j) — fixed and merged in PR #4941 (merge 503ff3a, head 14692ee). This issue auto-closed on the merge; recording the evidence here.

    What landed:

    • handleLaunchFailure now closes the failed launch's tracking issue as not planned after noting the failure (both wait paths).
    • New compensateOrphanedIssue helper covers the pre-enqueue shapes — packet validation (500) and enqueue (502) in POST /v1/sessions, and the same in POST /v1/tasks — note + close as not planned. The sessions enqueue-502 shape is the one that produced the orphans. Attach targets (caller-supplied issue_number) are never compensated.
    • GitHubClient.closeIssue (app PATCH state_reason / gh fallback).
    • Guard (packet item 3, test form): server.test.ts was itself filing REAL do-the-thing issues via the gh subprocess fallback (the fetch stub cannot intercept a subprocess; sessions default issue creation on). Proven live during this work: a clean-main baseline run filed do the thing #4937/do the thing #4938 open; runs with this fix filed do the thing #4936/do the thing #4939 and auto-closed them. Test requests now pass issue:false with the reason in a comment; suite runtime 16s → 0.7s.

    Tests: bun test pm-stack/dispatch/test on the laptop — 127 pass, 0 fail. tsc: one pre-existing error in untouched test/queue.test.ts only. Codex review on the PR could not run (usage limits, PR comments 6605825714/6605826421) — no findings existed to disposition; disposition recorded on PR #4941 (comment 6606057384).

    Cleanup: 66 body-verified orphan issues (exact dispatch footer body) closed as not planned, each with a comment pointing here — verified fresh afterwards: the only remaining open title matches are #2912 (same artifact but under an ACTIVE claim with user/review — left for its owning lane rather than yanked) and #4925 (a different, genuine issue about this class, currently claimed by another lane; this fix addresses its root cause too, its owner can close it against PR #4941).

    Note for the escalated placeholder: #4894 was among the 66 closed — its user/escalated ask (name the work or close as smoke test) is answered by this issue's class ruling: it was a smoke-test artifact with no spec. Reopen if that read is wrong.

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

    kind/bugSomething isn't working (prefixed form of the classic bug label)task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions