You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Service: name the holder (PID, liveness, age) when the runtime mutation lease is busy #6492
Find out why a supervised Windows proxy won't start when the runtime mutation lease is busy, and decide safely whether the lease is held by a live process or left stale.
What prevents this today?
When ocx start (supervised, via recoverStartStateUnderOwnershipLease) can't get the lease, it fails with only the path:
error: another process owns the runtime mutation lease at %USERPROFILE%\.opencodex\service-state.json.mutation.lock
at acquireOwnershipMutationLease (src/service/ownership-mutation-lease.mjs:185:40)
at recoverStartStateUnderOwnershipLease (src/cli/start-owner-fence.ts:12:22)
The Windows wrapper restarts the child every 5 seconds, so service.log fills with this stack. Meanwhile ocx service status only says "OpenCodex proxy not running" and doesn't mention lease contention.
To find the holder you have to open the lock directory and decode the v1-<pid>-<instance>-<token>.json owner file by hand. The obvious shortcut, deleting the lock directory, is unsafe when the holder is still alive. In our case it was alive: an external helper held the lease while waiting for the proxy to start, and the proxy waited on that helper.
What should OpenCodex do?
When lease acquisition times out, put the owner record that readOwner() already parses into the error:
holder PID, and whether that PID is alive
lease age (createdAt / owner file mtime)
if available cheaply, the holder's image name
Optionally, ocx service status / doctor could also report "runtime mutation lease held by PID N for Ns" while the lock exists.
Example usage or interface
error: another process owns the runtime mutation lease at …\service-state.json.mutation.lock
(holder pid 6236 [alive, python.exe], held 212s; stale leases are reclaimed after <STALE_MS> once the holder exits)
Alternatives or workarounds
Read the owner JSON in the lock directory by hand and check the PID with Get-Process. This works, but it isn't discoverable from the error message.
Additional context
Related but different: #5760, an updater deadlock on its own mutation lease, fixed in #5856. Here the holder is outside OpenCodex, so OpenCodex can't avoid the wait, but it can name who it is waiting for.
Version 2.76.0, Windows 11 x64. The same code is on dev.
Checks
I searched existing issues and documentation.
This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
Tracked by #6512, which adds a read-only holder status/error projection and preserves stale-lock recovery rather than deleting a live holder. I read its current five-file diff at 74d59b8; the focused tests explicitly retain the stale owner file on inspection. This is not merged or verified on your Windows service yet, so the issue remains open. PID/image/age are diagnostics, not permission to kill the process or manually delete its lease. No installed service or lock was changed here.
Fixed on dev by #6512 (815b1f6): a busy runtime mutation lease now reports the recorded holder (PID, liveness, age). Closing manually because PRs target dev; it ships in the next release.
Activity
Ingwannu commentedon Oct 4, 2026
Tracked by #6512, which adds a read-only holder status/error projection and preserves stale-lock recovery rather than deleting a live holder. I read its current five-file diff at 74d59b8; the focused tests explicitly retain the stale owner file on inspection. This is not merged or verified on your Windows service yet, so the issue remains open. PID/image/age are diagnostics, not permission to kill the process or manually delete its lease. No installed service or lock was changed here.
feat(service): name the holder when the runtime mutation lease is busy (
lidge-jun commentedon Oct 4, 2026
Fixed on
devby #6512 (815b1f6): a busy runtime mutation lease now reports the recorded holder (PID, liveness, age). Closing manually because PRs targetdev; it ships in the next release.Update from upstream 2.80.0 while preserving fork integrations (#9)