Skip to content

Fix bug 94: Add TTL to claims so interrupted runs don't leave stale claims - #95

Open
joewalker wants to merge 1 commit into
mainfrom
fix-bug-94-claim-ttl
Open

Fix bug 94: Add TTL to claims so interrupted runs don't leave stale claims#95
joewalker wants to merge 1 commit into
mainfrom
fix-bug-94-claim-ttl

Conversation

@joewalker

Copy link
Copy Markdown
Owner

Summary

This fixes bug #94 where an interrupted loop() run leaves a non-expiring claim, causing the prompt to be silently skipped forever on resume.

Root Cause

When loop() is terminated ungracefully (Ctrl+C/SIGINT/SIGKILL) while a prompt is claimed but not yet completed:

  1. The claim is persisted to the state file with a runId
  2. The finally block doesn't execute, so release() never runs
  3. The claim remains in the persisted state, owned by a now-dead runId
  4. On subsequent runs, claim() sees a claim with a different runId and returns false, causing the prompt to be skipped with "Skip (claimed elsewhere)"
  5. The expiresAt field existed but was never set or checked, so the stale claim persists indefinitely

Solution

  • Add CLAIM_TTL_MS constant (1 hour) for claim expiration - safely longer than any prompt's maximum runtime
  • Set expiresAt when creating new claims
  • Check for expired claims in claim() method and clean them up before checking ownership
  • Handle legacy claims without expiresAt that are owned by a different runId by treating them as stale

Changes

  • src/loop-states/file.ts: Modified the claim() method to check for expired claims and handle legacy claims

Testing

The fix ensures that:

  1. New claims have an expiration time (1 hour from creation)
  2. Expired claims are automatically cleaned up when claim() is called
  3. Legacy claims without expiresAt that are owned by a different run are treated as stale and removed
  4. The prompt can be reprocessed on subsequent runs after the claim expires or is cleaned up

Closes #94

…laims

This fixes the issue where an interrupted loop() run leaves a non-expiring
claim, causing the prompt to be silently skipped forever on resume.

Changes:
- Add CLAIM_TTL_MS constant (1 hour) for claim expiration
- Set expiresAt when creating new claims
- Check for expired claims in claim() method and clean them up
- Handle legacy claims without expiresAt that are owned by different runId

This ensures that stale claims from interrupted runs will eventually expire
and allow the prompt to be reprocessed on subsequent runs.

Closes #94
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

loop(): an interrupted run leaves a non-expiring claim, so the prompt is silently skipped forever on resume

1 participant