{"record":{"id":"554c7317d28d6b1e","repo":"stablyai/orca","slug":"worktree-registration-changed-during-deletion-c","errorCode":null,"errorMessage":"Worktree registration changed during deletion: ${canonicalWorktreePath}. Retry deletion.","messagePattern":"Worktree registration changed during deletion: (.+?)\\. Retry deletion\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ipc/worktrees.ts","lineNumber":2793,"sourceCode":"            )\n            runtime.clearOptimisticReconcileToken(args.worktreeId)\n            await withWorktreeRemoveStageSpan('metadata_purge', 'remote', async () => {\n              removeWorktreeMetadataAndTransientState(store, args.worktreeId, removalHostId)\n            })\n            notifyWorktreesChanged(mainWindow, repoId)\n            return removalResult ?? {}\n          }\n\n          const refreshedWorktrees = hasLocalWorktreeGitOptions\n            ? await listGitWorktreesStrict(repo.path, localWorktreeGitOptions)\n            : await listGitWorktreesStrict(repo.path)\n          const refreshedRegisteredWorktree = findRegisteredDeletableWorktree(\n            repo.path,\n            canonicalWorktreePath,\n            refreshedWorktrees\n          )\n          if (!refreshedRegisteredWorktree) {\n            throw new Error(\n              `Worktree registration changed during deletion: ${canonicalWorktreePath}. Retry deletion.`\n            )\n          }\n          try {\n            // Why: an archive hook can race another Git client that locks the row; recheck before linked-path/watcher/terminal teardown.\n            assertWorktreeUnlockedForRemoval(refreshedRegisteredWorktree)\n          } catch (error) {\n            throw new Error(\n              formatWorktreeRemovalError(error, canonicalWorktreePath, args.force ?? false)\n            )\n          }\n\n          // Why: `orca.yaml` shared directories are symlinked in too, and a\n          // directory-only ignore rule leaves those links untracked, so removal must\n          // tolerate and unlink them exactly like the per-user shared paths.\n          const linkedPaths = getWorktreeSharedLinkPaths(repo)\n          const ignoredLinkedPaths = args.force\n            ? []","sourceCodeStart":2775,"sourceCodeEnd":2811,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/worktrees.ts#L2775-L2811","documentation":"Thrown after archive hooks run, when the worktree list is refreshed and findRegisteredDeletableWorktree can no longer find the worktree at canonicalWorktreePath. The worktree's Git registration changed during deletion (another client removed/renamed it), so Orca stops and asks the caller to retry deletion from the new state rather than act on stale data.","triggerScenarios":"During a remove, between the initial listing and the post-hook refresh, another Git client deregisters, moves, or recreates the worktree so the refreshed list no longer contains it.","commonSituations":"Concurrent worktree operations (another Orca window, an IDE, CI, or a script) mutate the same repo's worktree set mid-delete; an archive hook itself ran Git that changed registrations.","solutions":["Retry the worktrees:remove call — the refreshed state will drive a clean decision.","Avoid running concurrent worktree-mutating operations against the same repo.","If it persists, inspect `git worktree list` to see what changed the registration."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"function isRegistrationChangedDuringDeletion(e: unknown): boolean {\n  return e instanceof Error && e.message.startsWith('Worktree registration changed during deletion')\n}","tryCatchPattern":"try {\n  await invoke('worktrees:remove', { worktreeId })\n} catch (e) {\n  if (isRegistrationChangedDuringDeletion(e)) {\n    // Refresh worktree state, then retry deletion once.\n    await invoke('worktrees:remove', { worktreeId })\n  } else throw e\n}","preventionTips":["Avoid concurrent worktree-mutating operations on the same repo.","Retry from refreshed state when registration changes mid-delete.","Check archive hooks for Git commands that mutate registrations."],"tags":["worktree-remove","concurrency","retry","registration-race"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}