Skip to content

fix(web): archive tasks from the board and release provably dead runs - #105

Merged
jusso-dev merged 1 commit into
mainfrom
fix/task-archive-and-force-cancel
Jul 30, 2026
Merged

fix(web): archive tasks from the board and release provably dead runs#105
jusso-dev merged 1 commit into
mainfrom
fix/task-archive-and-force-cancel

Conversation

@jusso-dev

Copy link
Copy Markdown
Owner

Two separate ways a work item became permanently stuck. Reported as "stuck jobs queued in the task board that I can't delete" — that's actually both problems at once.

There was no delete or archive path anywhere

Not in the UI, not in the API. archivedAt existed on the table and every list already filtered on it, but nothing could set it — the only way to clear a task was a manual database update. (That's what I had to do earlier to clean up my own verification tasks, which should have tipped me off then.)

  • PATCH /api/v1/tasks/[id] now accepts { archived }, audited as task.archived / task.restored.
  • Soft delete, never a row delete, so audit events referencing the task keep a valid target.
  • Archiving is refused while a run is queued or running. Hiding a task whose agent is still burning budget and may still write evidence is worse than leaving it visible. Cancel first — and the button says so.

Cancel could wedge, which is what made them unrecoverable

POST /api/v1/tasks/[id]/cancel called the gateway and threw on any failure. So a run the gateway had lost — dead worker, expired lease, orphaned record — could never be released. That left the task simultaneously undeletable (no archive path) and undispatchable (A run is already in flight). Permanently stuck, by construction.

Cancel now force-releases a run only when it provably cannot still be executing: both the lease and the deadline have passed, or the run row is gone entirely.

Anything else still refuses, with a 502 and an explicit message, because the alternative is worse than a stuck task: Muster reporting a run cancelled while the gateway is still executing it, and an operator dispatching a second one on top. A forced release records that the gateway did not confirm and why, both in cancellationReason and the response.

Note

I could not reproduce a genuinely wedged run on the homelab — the one queued task settled to completed while I was inspecting it, which is the #100 settle fix working. So this is a fix for the class of failure, verified by reading the paths rather than by reproducing one. The force-release rule is deliberately conservative for that reason.

🤖 Generated with Claude Code

Two ways a work item became permanently stuck.

There was no delete or archive path at all — not in the UI, not in the
API. 'archivedAt' existed and every list already filtered on it, but
nothing could set it, so the only way to clear a task was a manual
database update.

- PATCH /api/v1/tasks/[id] accepts { archived }, audited as
  task.archived / task.restored.
- Soft delete, never a row delete, so audit events that reference the
  task keep their target.
- Archiving is refused while a run is queued or running: hiding a task
  whose agent is still burning budget and may still write evidence is
  worse than leaving it visible. Cancel first.

Cancel itself could wedge. It called the gateway and threw on any
failure, so a run the gateway had lost — dead worker, expired lease —
could never be released, leaving the task undeletable and
undispatchable at once.

Cancel now force-releases a run only when it provably cannot still be
executing: both the lease and the deadline have passed, or the run row
is gone. Anything else still refuses with 502 rather than reporting a
run cancelled while the gateway may still be running it. A forced
release records that the gateway did not confirm, and why.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jusso-dev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 14 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d0531046-ac4c-4824-b91c-da79b8247f17

📥 Commits

Reviewing files that changed from the base of the PR and between 3b96c9a and 0cc31fa.

📒 Files selected for processing (6)
  • apps/web/app/api/v1/tasks/[id]/cancel/route.ts
  • apps/web/app/api/v1/tasks/[id]/route.ts
  • apps/web/features/operations/operations-view.test.ts
  • apps/web/features/operations/operations-view.tsx
  • apps/web/lib/queries/hooks.ts
  • apps/web/lib/task-domain.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jusso-dev
jusso-dev merged commit ecce1d7 into main Jul 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant