Desktop: manual Archive deletes worktree with uncommitted changes, no confirmation

Resolved 💬 2 comments Opened May 6, 2026 by jonathanglasmeyer Closed May 13, 2026

What happens

The "Archive" button in Claude Code Desktop unconditionally deletes the session's git worktree, including any uncommitted local changes — with no confirmation dialog and no dirty-state check.

The session JSON is preserved (just flagged isArchived: true), but anything in the worktree filesystem that wasn't committed/pushed is gone.

Repro

  1. Start a session in a Claude-Desktop-managed worktree.
  2. Have any uncommitted/unpushed work in the worktree.
  3. Trigger Archive — either:
  • Right-click session → "Archive" in the context menu, or
  • Press A while the context menu is open (this is the worse footgun: an accidental keystroke with the menu visible silently nukes the worktree).
  1. Worktree directory is removed via git worktree remove --force (with fs.rm recursive-force fallback). No prompt, no undo.

Code path (extracted from app.asar @ v1.5354.0)

UI side (ion-dist/.../index-BNbM_KX7.js, cbc59a8af-D4zw98by.js):

await archive(sessionId, { cleanupWorktree: true })

Hardcoded true everywhere it's called.

Main process (teardownSession):

if (i.cleanupWorktree !== false && o.worktreePath) {
  // removeWorktree
}

Worktree removal:

git -c core.longpaths=true worktree remove --force <path>
// fallback:
await fs.rm(path, { recursive: true, force: true })

--force overrides git's "uncommitted changes" guard; the fs.rm fallback bypasses it entirely.

Searching the whole bundle: every caller of archive / archiveSession passes either cleanupWorktree: true or undefined (which the !== false check still treats as "delete"). The backend has the capability to skip cleanup, but no code path uses it.

Why this is the wrong default for manual archive

Aggressive cleanup makes sense for AutoArchiveEngine (PR merged → worktree disposable). It's the wrong default for the user-facing Archive button, where the user may have:

  • Uncommitted experimental changes
  • Local-only branches not yet pushed
  • Work-in-progress not ready for PR

There's also an asymmetry users don't expect: session JSON is soft-deleted (preserved + flagged, recoverable via tooling), worktree is hard-deleted with --force. "Archive" reasonably implies the same retention semantics for both.

Related: #54047 (transcript deletion on PR-merge cleanup, closed). Same root pattern — cleanup decisions coupled to a single irreversible flag.

Ask

For the manual Archive flow, at minimum one of:

  1. Confirmation dialog when the worktree has uncommitted changes or unpushed commits.
  2. UI toggle "Also delete worktree" (visible, defaultable).
  3. Soft-delete the worktree (move to Trash / ~/.claude/archived-worktrees/) instead of recursive force-delete.
  4. Drop --force, surface the git error to the user, let them decide.

The backend already supports cleanupWorktree: false end-to-end — only the UI never sends it.

Environment

  • Claude Desktop v1.5354.0
  • macOS 15.4 (Darwin 25.4.0)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗