stablyai/orca · warning · Error

Worktree registration changed during deletion: ${canonicalWo

Error message

Worktree registration changed during deletion: ${canonicalWorktreePath}. Retry deletion.

What it means

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.

Source

Thrown at src/main/ipc/worktrees.ts:2793

            )
            runtime.clearOptimisticReconcileToken(args.worktreeId)
            await withWorktreeRemoveStageSpan('metadata_purge', 'remote', async () => {
              removeWorktreeMetadataAndTransientState(store, args.worktreeId, removalHostId)
            })
            notifyWorktreesChanged(mainWindow, repoId)
            return removalResult ?? {}
          }

          const refreshedWorktrees = hasLocalWorktreeGitOptions
            ? await listGitWorktreesStrict(repo.path, localWorktreeGitOptions)
            : await listGitWorktreesStrict(repo.path)
          const refreshedRegisteredWorktree = findRegisteredDeletableWorktree(
            repo.path,
            canonicalWorktreePath,
            refreshedWorktrees
          )
          if (!refreshedRegisteredWorktree) {
            throw new Error(
              `Worktree registration changed during deletion: ${canonicalWorktreePath}. Retry deletion.`
            )
          }
          try {
            // Why: an archive hook can race another Git client that locks the row; recheck before linked-path/watcher/terminal teardown.
            assertWorktreeUnlockedForRemoval(refreshedRegisteredWorktree)
          } catch (error) {
            throw new Error(
              formatWorktreeRemovalError(error, canonicalWorktreePath, args.force ?? false)
            )
          }

          // Why: `orca.yaml` shared directories are symlinked in too, and a
          // directory-only ignore rule leaves those links untracked, so removal must
          // tolerate and unlink them exactly like the per-user shared paths.
          const linkedPaths = getWorktreeSharedLinkPaths(repo)
          const ignoredLinkedPaths = args.force
            ? []

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Retry the worktrees:remove call — the refreshed state will drive a clean decision.
  2. Avoid running concurrent worktree-mutating operations against the same repo.
  3. If it persists, inspect `git worktree list` to see what changed the registration.
Defensive patterns

Strategy: retry

Type guard

function isRegistrationChangedDuringDeletion(e: unknown): boolean {
  return e instanceof Error && e.message.startsWith('Worktree registration changed during deletion')
}

Try / catch

try {
  await invoke('worktrees:remove', { worktreeId })
} catch (e) {
  if (isRegistrationChangedDuringDeletion(e)) {
    // Refresh worktree state, then retry deletion once.
    await invoke('worktrees:remove', { worktreeId })
  } else throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/554c7317d28d6b1e. Report an issue: GitHub.