[Bug] Windows: session lease can be permanently stuck, and a live lease can be reclaimed when owner.json is briefly unreadable #1478
andreolf
started this conversation in
Bug reports
Replies: 1 comment
|
Confirming on Windows 11. Still present in v0.8.0 — if (code !== "EEXIST" && code !== "ENOTEMPTY") throw error;On Windows, Reproduced after force-killing the process tree ( |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Affected area
Coding agent and CLI
What happened?
Two related bugs in
packages/coding-agent/src/core/session-lease.ts, both most likely to fire on Windows. (Both were in the now-closed #727; the second was independently confirmed by @BILLKISHORE.)Bug 1 — a stale lease permanently blocks recovery on Windows.
acquireSessionLeaseclaims a lease by renaming a candidate dir onto the lease dir; on failure it reclaims the lease only when the error isEEXIST/ENOTEMPTY:renameSynconto an existing non-empty directory reportsEPERM/EACCESon Windows, so the error rethrows,reclaimStaleLeasenever runs, and a stale lease blocks the session indefinitely.Bug 2 — a live lease can be reclaimed when
owner.jsonis momentarily unreadable (more serious).readLeaseOwnercollapses every failure intoundefined, so the caller can't tell "owner.json absent" (no owner) from "owner.json unreadable" (transient I/O error) and falls through toreclaimStaleLease. On Windows a briefly held handle (antivirus, search indexer) makes an unreadableowner.jsonroutine — so a live session's lease gets reclaimed and two processes believe they own the same session. Fixing Bug 1 widens this path on Windows.Steps to reproduce
Identified by source inspection plus a unit-level repro (not a live end-to-end run — same basis as the review on #727). Deterministic repro for Bug 2, no Windows needed:
owner.jsonfor a process that is still alive.owner.jsonpresent-but-unreadable: replace the file with a directory namedowner.jsonin the lease dir, soreadFileSyncthrowsEISDIR— a stand-in for a transiently locked file.acquireSessionLeasefor the same session.Bug 1 surfaces on Windows when
renameSynconto the existing lease dir returnsEPERM/EACCESinstead ofEEXIST/ENOTEMPTY, so the reclaim path is never reached.Expected behavior
EPERM/EACCESon an existing rename target should be treated likeEEXIST/ENOTEMPTY.owner.jsonexists but can't be read (transient error, not a missing file), the lease should be treated as held by a live owner and NOT reclaimed — matchingisProcessAlive, which returnstrueonEPERM. Only a genuinely absentowner.jsonshould be reclaimable.Prime Agent version
Identified from source on main (paths also present in the 0.7.x line); not tied to a single running build.
Environment
Analysis performed on macOS. Affected platform is Windows (Bugs 1 and 2, due to renameSync error codes and routine transient file locking); Bug 2's repro is cross-platform.
Additional context
Suggested direction:
EPERM/EACCESonwin32in the rename-error filter.absent/unreadable/ownerinreadLeaseOwnerand treat unreadable as a live owner (mirrorisProcessAlive'sEPERMhandling).Both were in the now-closed #727, where Bug 2 was independently confirmed by @BILLKISHORE. Happy to provide a PR with tests if a maintainer wants to pursue this.
All reactions