{"version":"2.1.210","anchor":"stale-worktree-lock-auto-cleanup","canonical_anchor":"stale-worktree-lock-auto-cleanup","heading":"Stale Worktree Lock Auto-Cleanup","tier":null,"area":null,"scope":null,"heads_up":null,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.210\/e\/stale-worktree-lock-auto-cleanup","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.210","markdown":"### Stale Worktree Lock Auto-Cleanup\n\n**What**\n\nClaude Code now automatically detects and releases worktree locks that were left behind by processes that have since exited, rather than leaving them to block future operations.\n\n**Details**\n\n- On each sweep, the worktree registry is scanned for locks whose lock-reason string encodes a PID. Only reasons matching the pattern `^claude (?:agent|session) .{1,255} \\(pid (\\d{1,10})(?: start .{1,255})?\\)$` (and no longer than 512 characters) are eligible; lock reasons that don't follow this format are skipped entirely.\n- If `process.kill(pid, 0)` returns `ESRCH` (no such process), the lock is treated as stale and released. Any other result (process exists, or PID \u2264 1 \/ non-integer) is treated as live and left alone.\n- The per-sweep cap is **50 releases**: once 50 stale locks have been released in one sweep, the remainder are logged and deferred to a later sweep with the message `\"releaseStaleClaudeWorktreeLocks: per-sweep cap of 50 reached; remaining stale locks will be reconciled on later sweeps\"`.\n- Worktrees with no `.git` file at their path are also skipped, preventing cleanup of already-removed trees.\n- The registry is re-read at release time (double-checked before each individual unlock) to prevent TOCTOU races where another process might have claimed the lock between the scan and the release.\n- The current session's own worktree is always excluded from cleanup (matched by resolved real path).\n- When at least one lock is released, a `tengu_worktree_stale_lock_released` telemetry event is emitted with `{ attempted: N }`, and a debug log reports the count: `\"releaseStaleClaudeWorktreeLocks: attempted release of N stale liveness lock(s)\"`.\n\n**Evidence**\n\nCleanup function (search for `\"releaseStaleClaudeWorktreeLocks: attempted release of\"`) and PID check logic (search for `\"stale liveness lock(s) in\"`); cap constant (`$zc = 50`); lock-reason regex (`Mtt`)"}