You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
🤖 bug: a crash during a delegated workspace creation orphans the workspace #4983
WorkspaceTurnManager.createWorkspaceTurn (mode "new") creates the target workspace (workspaceService.create) and only later persists the workspace-turn handle record (taskHandleStore.upsertWorkspaceTurn). Since #4841, every return or throw in between removes the created workspace through the _creationFinalizer (removeWhileTaskTreeLocked, which keeps a branch the creation only reused). A crash (SIGKILL, power loss) during the awaits in that window still leaves the checkout and its config row without any handle record. The owner cannot reach the workspace with mode "existing" (invalid_scope), so it stays orphaned until the user removes it by hand.
The awaits in the window are the target agent validation, resolveNodeAgentAiSettings, the lifecycle lock, desktop admission, the live-owner lock, and the record write itself.
The startup sweep clearOrphanedDelegatedConsentDefaults() already visits rows tagged mux.taskHandleId, but it only clears their pending consent.
Fix direction
At startup, find rows tagged mux.taskHandleId that have no matching handle record and whose live-owner lock is not held by a live process. Remove them with a forced removal that keeps the branch (the creation's own createdBranch is not persisted, so keeping it is the lossless choice). Do this in the same pass as the consent sweep.
This split out of #4819, whose non-crash exits #4841 fixed.
PR #5130 tried an automatic startup sweep that removes a crash-orphaned delegated target. It was closed unmerged and parked. Three review rounds each found a different missing safety gate, and the orphan is a visible, clean workspace the user can remove by hand. The branch delegated-creation-orphan-sweep (head 8febd715d0) is the reference implementation.
A future attempt must satisfy all of these:
(a) An unforgeable binding between handle, target row and owner.workspace.create accepts any tags, and a stale live-owner lock proves only that a handle id existed. For example, the lock or record written at creation carries the target workspaceId and ownerId, and the sweep verifies both before it acts.
(b) An admission and mutation fence taken before the emptiness checks, so no turn, exec, terminal or other activity can start between the check and the deletion. This includes the sweeping backend's own activity. 🤖 fix: remove delegated targets orphaned by a crash before their handle record #5130 did this with a removal option that runs the checks under the removal's gate, admission hold and pendingRemoval marker, with a strict gate policy.
(c) Durable external-app markers honored. A native terminal or external editor takes no lease and may outlive the crash (hasUntrackableExternalAppOpen()).
(d) Proof that the target never ran work: no chat history, a clean checkout, and no commit that only its branch holds. The branch is kept.
Picked up by the issue coordinator: workspace plan-crash-orphan-sweep-4983, branches delegated-creation-binding (backend) and delegated-creation-banner (UI), as a 2-PR native stack.
Approach (approved): surface orphaned delegated targets to the user instead of deleting them. A creator-written row field binds the target row to its handle and owner; a startup pass flags rows whose setup never finished; a banner offers the normal confirmed removal or Keep.
Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $10.22
Activity
linear-code commentedon Sep 28, 2026
MUX-383
ThomasK33 commentedon Sep 29, 2026
Picked up by the issue coordinator: workspace delegated-creation-orphan-sweep, branch delegated-creation-orphan-sweep
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:highThomasK33 commentedon Sep 29, 2026
Parked: requirements for a future fix
PR #5130 tried an automatic startup sweep that removes a crash-orphaned delegated target. It was closed unmerged and parked. Three review rounds each found a different missing safety gate, and the orphan is a visible, clean workspace the user can remove by hand. The branch
delegated-creation-orphan-sweep(head8febd715d0) is the reference implementation.A future attempt must satisfy all of these:
workspace.createaccepts any tags, and a stale live-owner lock proves only that a handle id existed. For example, the lock or record written at creation carries the target workspaceId and ownerId, and the sweep verifies both before it acts.pendingRemovalmarker, with a strict gate policy.hasUntrackableExternalAppOpen()).Facts established in #5130:
readWorkspaceTurnFilereturns null for corrupt records and for records written by a newer build, so a null there does not prove the record is absent.Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:highThomasK33 commentedon Sep 29, 2026
Picked up by the issue coordinator: workspace plan-crash-orphan-sweep-4983, branches delegated-creation-binding (backend) and delegated-creation-banner (UI), as a 2-PR native stack.
Approach (approved): surface orphaned delegated targets to the user instead of deleting them. A creator-written row field binds the target row to its handle and owner; a startup pass flags rows whose setup never finished; a banner offers the normal confirmed removal or Keep.
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:high• Cost:$10.22feat: show interrupted delegated workspaces with Remove and Keep (#4983)
tests: delegated-creation binding and orphan flagging (#4983), failin…
fix: bind delegated targets to their creating handle and flag orphans…
feat: show interrupted delegated workspaces with Remove and Keep (#4983)
🤖 fix: bind delegated targets to their creating handle and flag orpha…
🤖 feat: show interrupted delegated workspaces with Remove and Keep (c…
🤖 fix: key the interrupted-delegation banner by workspace and harden …
🤖 fix: name what workspace removal deletes on each runtime (coder#5211)
🤖 feat: let scratch chats create workspace turns in new scratch chats (…
🤖 fix: open the metadata stream with a snapshot so no startup change …
🤖 tests: let the creator's init settle before the delegatedConsent st…