-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
Stale lock recovery ignores createdAt when recorded PID is reused #86814
Copy link
Copy link
Closed
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.Auth, provider routing, model choice, or SecretRef resolution may break.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.Auth, provider routing, model choice, or SecretRef resolution may break.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Bug
shouldRemoveDeadOwnerOrExpiredLock()currently trusts a live recorded PID before checkingcreatedAt. If the original lock owner died and the OS later reused the same PID for an unrelated process, stale recovery never considers the lock expired.Current main:
This means a lock payload with both
pidand an expiredcreatedAtis kept forever as long as any process currently has that PID.Production impact
We hit this on macOS with OpenClaw
2026.5.22 (a374c3a)during Discord replies./Users/betalpha/.openclaw/agents/tino/agent/auth-profiles.json.lockfrom 2026-05-23.markAuthProfileSuccess()tried to acquire that lock afterembedded run done.createdAt, the lock was not reclaimed.Related context: #85822. We posted the full production timeline and local hotfix result there: #85822 (comment)
Expected behavior
If a lock payload has
createdAt, stale expiry should be evaluated before PID liveness, or PID liveness should only be trusted together with a stronger owner identity than PID alone.A minimal fix is:
This preserves the existing PID-dead fast path for non-expired locks, but lets explicit stale expiry do what
staleMspromises even when the OS has reused the PID.Regression test suggestion
Add a test for a payload like:
with:
nowMslater thancreatedAt + staleMsisPidDefinitelyDead: () => falseExpected result should be
truebecause the lock is expired even though the PID is currently alive.