[BUG] Desktop remote/SSH: archive never cleans up worktrees since 2.1.235 — app requires hardened git.status(baseRepo) but only ships a 2026-07-06 daemon, so "reconnect to deploy the updated daemon" is a no-op

Status Open
Reported on v2.1.235
Maintainer reply None cached
Activity 1 comment · opened Aug 22, 2026

Summary

Since ~2.1.235, archiving a remote (SSH/devcontainer) session in the Claude desktop app never cleans up its git worktree. The app requires a hardened git.status(baseRepo) RPC from the remote daemon, but the daemon it deploys was built 2026-07-06 — roughly six weeks before the requirement landed. Every archive fails the pre-delete dirty-check and leaks the worktree.

The error tells you to reconnect to deploy an updated daemon. Reconnecting redeploys the same binary, byte-identically. There is no newer daemon on the machine, so the documented remedy cannot succeed from the user side.

Environment

  • Claude desktop app on macOS
  • Remote devcontainers over SSH on a separate Linux host (3 independent containers, same behaviour in all)
  • ccd-cli 2.1.237
  • Remote daemon: claude-ssh 5db5e4a12f88487e47c2c48259b69a2d630bb3f7 (built 2026-07-06T20:46:38Z)

Reproduce

  1. Open a Claude Code Desktop session against a remote/SSH devcontainer (session gets a worktree under .claude/worktrees/).
  2. Archive the session.
  3. The worktree remains on disk; ~/Library/Logs/Claude/main.log shows the error below.

Reproduced with a brand-new session created and archived immediately, on a freshly respawned daemon.

The error

[warn]  getSessionUncommittedChanges: remote check failed for session local_34dd3473-…
[error] Failed to clean up worktree for session local_34dd3473-…
Remote daemon predates hardened git.status (baseRepo); refusing unhardened dirty-check
for "/workspace/.claude/worktrees/new-session-fbdec3" — reconnect to deploy the updated daemon
    at Ot.getRemoteUncommittedChanges (…/app.asar/.vite/build/index.chunk-CgncK-Xq.js:1:56502)
    at e.getSessionUncommittedChanges (…/app.asar/.vite/build/index2.chunk-BoMiMWA8.js:1:357508)
    at Object.getUncommittedChanges (…/app.asar/.vite/build/index.chunk-2g9lpGtG.js:1:24092)

Why the suggested remedy cannot work

Killed the --serve daemon and reconnected, forcing a full respawn + redeploy. The app rewrote the binary — with identical content:

before:  6336664 bytes, mtime 2026-08-20 23:16
after:   6336664 bytes, mtime 2026-08-22 12:13

The respawned daemon self-reports the same pre-hardening build:

$ ~/.claude/remote/srv/5db5e4a12f88487e47c2c48259b69a2d630bb3f7/server --version
claude-ssh 5db5e4a12f88487e47c2c48259b69a2d630bb3f7 (built 2026-07-06T20:46:38Z)

Only two daemon builds exist on disk, and both predate the requirement:

5db5e4a1…  built 2026-07-06T20:46:38Z   ← the one deployed
7c2f88d1…  built 2026-07-02T06:09:19Z

Verified across three independent devcontainers, all respawned at the same moment; all three came back on the 2026-07-06 build, and archiving still fails.

Note the two remote artifacts are on very different update cadences — ccd-cli moved 2.1.234 → 2.1.235 → 2.1.237 in three days, while the daemon has not moved since early July. The hardening appears to have shipped in the app without a matching daemon build.

Version boundary

| Session archived | ccd-cli at the time | Worktree |
|---|---|---|
| 2026-08-19 03:30Z | 2.1.234 (installed Aug 18 18:46) | cleaned up correctly |
| 2026-08-20 21:40Z | 2.1.235 (installed Aug 20 15:57) | leaked |
| every archive since | 2.1.235 / 2.1.237 | leaked (9 of 9) |

Last good is 2.1.234, matching the boundary independently reported in #88836.

Impact

Worktrees accumulate silently — one per archived session, each a full checkout. In our repo this is not cosmetic: worktrees are allocated a port/DB offset from a pool of 10, so once the leaked worktrees fill it, the test suite fails to start with an error that names nothing relevant (claim-offset: no free offset). It took a full debugging session to trace that back to archive cleanup.

Ruled out

  • Not the remote setup itself. Cleanup worked in this exact SSH/devcontainer arrangement on Jul 29, Aug 4, Aug 9 and Aug 19; the container and its remote tooling predate all of them.
  • Not git locks. No worktree is locked (git worktree list --porcelain reports none; no locked files).
  • Not dirty worktrees. 7 of 8 leaked worktrees are clean per git status --porcelain; git worktree remove succeeds on them by hand.
  • Not a stale daemon process. Killing it and letting the app respawn reproduces the failure on the fresh process.

Related

  • #88239 — same consequence (a refused pre-delete check leaks the worktree) but local rather than remote, and gated on commit reachability after a squash merge rather than a daemon version handshake. Possibly the same hardening push landing on two surfaces.
  • #88253 — Desktop's own git subprocesses failing inside worktrees, but caused by macOS sandbox EPERM, not a version handshake.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗