fix: surface workspace delete failures from AgentsPage archive flow - #26900
Conversation
…elete fails Delete the workspace first, archive the chat second. If the delete fails for anything other than 404/410, the chat stays in the sidebar so the user can retry. The error toast names the workspace and links to it for manual deletion. On success, surface queue context from the build response: warn when no provisioners are available (queue_size = 0) or note the queue depth when queued behind other jobs.
|
/coder-agents-review |
|
Chat: Review posted | View chat Review historydeep-review v0.9.0 | Round 4 | Last posted: Round 4, 18 findings (2 P2, 5 P3, 6 Nit, 5 Note), APPROVE. Review Finding inventoryFindings
Contested and acknowledged(none) Round logRound 1Netero-only. 1 P2. Reviewed against d219f96..e8b7b8d. Round 4Panel (11 reviewers). CRF-15 through CRF-17 resolved (2 fixed, 1 accepted). 0 P2, 0 P3, 1 Nit new. Reviewed against d219f96..34f7903. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
First-pass review (mechanical checks only). The full review panel has not yet reviewed this PR; the panel will review after this finding is addressed.
The swap to delete-first is sound and the test coverage is good (66% test density, all new exports covered). One defect in the error path needs fixing before the panel round.
1 P2.
🤖 This review was automatically generated with Coder Agents.
…s, tone down queue toast
|
/coder-agents-review |
There was a problem hiding this comment.
CRF-1 (R1) is fixed: ArchiveAndDeleteError tags which step failed and notifyDeleteFailed branches correctly. Clean.
The ordering swap is the right call and the error-handling improvements are solid. Test coverage is good (64% density, all new exports covered, both error branches and the fallback tested). One issue in the queue-feedback feature needs attention before merge.
Severity counts: 1 P2, 5 P3, 3 Nit, 3 Note.
R2 commit subject is 93 chars (72-char convention). Two changes in one subject line; the primary fix alone would fit.
The implementation plan in the PR description is stale: it promises the queue_size=0 toast says "no provisioners available," but the R2 code changed it to "Delete enqueued." A reviewer reading the description gets a wrong mental model.
"The user sees 'enqueued' and moves on, missing that something might be wrong." (Leorio)
site/src/pages/AgentsPage/AgentsPage.tsx:431
P3 [CRF-3] onSettled navigates the user away on error, undermining the PR's retry-surface goal.
Both .mutate() call sites (line 431 for "proceed", line 464 for "confirm") use onSettled for navigateAfterArchive, which fires on error too. With the delete-first reordering, a delete failure now leaves the chat visible in the sidebar, but the user gets redirected to /agents anyway.
The author already applied the correct principle for the archive-only path at line 447 (onSuccess, with the comment "a failed archive should not redirect the user"). The same reasoning now applies here: a failed delete leaves the user with an entry point they shouldn't be navigated away from.
Fix: move navigateAfterArchive into onSuccess at both call sites. For the confirm path (line 464), keep setPendingArchiveAndDelete(null) in onSettled so the dialog closes regardless.
(Kite P3, Hisoka Note)
🤖
🤖 This review was automatically generated with Coder Agents.
|
/coder-agents-review |
There was a problem hiding this comment.
All R2 findings addressed. The queue feedback now reads matched_provisioners.count (populated on POST). Navigation callbacks use onSuccess. Cache invalidation runs on archive-failure. ArchiveAndDeleteError uses ES2022 cause chain. Tests cover every branch. Clean.
11 of 13 reviewers found no issues. 2 Note, 1 Nit remaining (none blocking).
"I tried to build a case against this and could not. The problem is correctly understood, the solution is proportional, and the fix is at the right causal level." (Pariston)
🤖 This review was automatically generated with Coder Agents.
|
/coder-agents-review |
There was a problem hiding this comment.
All R3 findings resolved. CRF-15 fixed cleanly with deleteEnqueued flag on ArchiveAndDeleteError. CRF-17 fixed (consistent make prefix). 54 tests pass. No regressions.
10 of 11 reviewers found no issues. 1 Nit remaining (PR title length for squash-merge subject).
This PR has been through 4 rounds and 18 findings. Every substantive finding was fixed. The ordering swap, step-tagged errors, onSuccess navigation, cache invalidation, and matched_provisioners.count queue signal are all correct and well-tested.
🤖 This review was automatically generated with Coder Agents.
There was a problem hiding this comment.
Pull request overview
This PR fixes a UX failure mode in the AgentsPage “Archive & delete workspace” flow where archiving could remove the chat from the sidebar before a failed workspace-delete enqueue was surfaced, leaving users without a retry entry point and potentially leaving the workspace behind unnoticed.
Changes:
- Reorders the archive/delete helper to delete first, archive second, and wraps failures in a typed
ArchiveAndDeleteErrortagged by failing step. - Updates AgentsPage mutation handlers to navigate away only on success, and to toast actionable, step-specific error messages (including an “Open workspace” action on delete failures).
- Adds queue-state warning logic based on
matched_provisioners.countfrom the POST/workspacebuildsresponse, plus unit tests for the new behaviors.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| site/src/pages/AgentsPage/utils/agentWorkspaceUtils.ts | Reorders delete+archive flow, adds typed step errors, and adds toast helpers for queue-state warnings and step-specific failures. |
| site/src/pages/AgentsPage/utils/agentWorkspaceUtils.test.ts | Adds/updates unit tests covering new error-wrapping, ordering, and toast branching behavior. |
| site/src/pages/AgentsPage/AgentsPage.tsx | Integrates the new helper outputs, improves navigation-on-error behavior, invalidates caches appropriately, and uses the new toast helpers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
DanielleMaywood
left a comment
There was a problem hiding this comment.
I'm approving although I'm going to be honest... I think maybe this is a symptom of the existing mess but the approach taken here feels quite messy
Right-clicking Archive & delete workspace on an agent chat could leave the workspace behind without the user noticing. The archive step ran first and removed the chat from the sidebar, so when the delete enqueue failed the user lost the surface to retry and the workspace lingered.
Fix
ArchiveAndDeleteErrortagged withstep: "delete" | "archive". The toast branches on the tag:deletefailures show an actionable "Open workspace" link,archivefailures explain the delete already ran so no manual deletion is needed.onSuccessonly (previouslyonSettled), so a delete failure keeps the chat's retry surface reachable. The confirm dialog still closes ononSettled.matched_provisioners.countis 0. That field is populated onPOST /workspacebuilds;job.queue_position/job.queue_sizeare not.No backend changes. No new API surface.
Out of scope
POST /workspacebuildsonly means the build was queued; the workspace page already surfaces builds that fail to run, and the underlying cause is server/infra.DormantAttoday (onlystartis), so the normal delete path already accepts dormant workspaces.Implementation notes
Problem
archiveChatAndDeleteWorkspaceused to archive first, then delete. On delete failure the chat was already archived and removed from the sidebar, so the user lost the entry point to retry. A generic toast fired, but by then they had usually moved on.Approach
ArchiveAndDeleteError { step: "delete" | "archive" }is thrown from the helper. Callers can produce a message that matches the step that actually failed.deletefailed → "Failed to delete workspace {name}." with description "The chat was not archived. Open the workspace to delete it manually." and an "Open workspace" action.archivefailed → "Deleting {name}, but failed to archive the chat. {cause}." No action button: the delete is already on its way.archiveAndDeleteMutation.mutatecall sites moved fromonSettledtoonSuccessfor the navigation callback. The confirm dialog still usesonSettledto close itself.invalidateWorkspaceMutationQueriesruns fromonErrorso any other view reflects the deletion.POST /workspacebuildshardcodesjob.queue_position = 0and never setsqueue_size, so the earlier queue-based branching would have been dead code.matched_provisioners.countis populated on POST, so the toast branches on that instead and only warns when count is 0.Files
site/src/pages/AgentsPage/utils/agentWorkspaceUtils.tssite/src/pages/AgentsPage/utils/agentWorkspaceUtils.test.tssite/src/pages/AgentsPage/AgentsPage.tsxThis PR was generated by Coder Agents on behalf of @johnstcn.