mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
When a user tries to archive-and-delete a chat from /agents but the workspace is already gone, the UI showed a "Failed to look up workspace for deletion" toast and blocked the archive. This change detects the workspace-gone response and archives the chat without attempting deletion. ## Changes The backend returns 410 Gone for soft-deleted workspaces and 404 for workspaces that do not exist or the user cannot access. `isWorkspaceNotFound()` detects both status codes. `resolveArchiveAndDeleteAction()` now returns `"archive"` when the workspace preflight fetch gets a 404 or 410, and the page branches on that action to call the existing archive mutation directly. The `archiveAndDeleteMutation` also tolerates these status codes from `deleteWorkspace()` to handle the race where the workspace disappears between the preflight lookup and the actual delete call. The mutation body was extracted into a testable `archiveAndDeleteWorkspace()` utility so the tolerance logic has direct test coverage. A `navigateAfterArchive()` helper consolidates the post-archive redirect logic that was previously duplicated across the proceed, confirm, and archive paths. ## Pre-existing patterns preserved - The `"proceed"` and `"confirm"` archive-and-delete paths use `onSettled` for navigation, matching the existing behavior before this change. Only the new `"archive"` path uses `onSuccess` since it has no workspace deletion step that should still navigate on partial failure. - `isWorkspaceNotFound()` uses the same `isAxiosError(error) && error.response?.status` pattern already used in several places in `site/src/api/api.ts`. The backend 404 ambiguity (deleted vs unauthorized) is documented in the JSDoc. - The pre-existing double-submit race during the async preflight window is unchanged.