Skip to content

fix(purchase): reaper CAS should only reap rows still in the status they were listed under #1043

Closed

Description

@cristim

The stuck-purchase reaper's per-row CAS (reapOne in internal/purchase/reaper.go) transitions with stuckStatuses (approved|running -> failed) regardless of which status the SELECT listed the row under.

Scenario: the reaper lists an old approved row; before its CAS runs, RecoverStrandedApprovals claims the same row approved -> running and starts the re-drive. The reaper's CAS still matches running, so the row is marked failed while the purchase is in flight. Provider idempotency tokens should prevent a double buy, but History can show failed for a purchase that went through.

This predates #1042 (the CAS has always accepted both statuses); #1042 makes the recovery and reaper windows closer, so the overlap is a bit more likely. Found in the independent review of #1042 (non-blocking there).

Suggested fix: pass the listing pass's status (the status the row was selected under) as fromStatuses to TransitionExecutionStatus, so an approved-pass row only reaps if it is still approved. Add a test where the row moves to running between list and CAS and assert RaceLost.

Activity

  1. cristim commented on Oct 17, 2026

    @cristim
    MemberAuthor

    Claiming: working on this [claude-cc-impl]

  2. self-assigned this
    on Oct 17, 2026
  3. cristim commented on Oct 17, 2026

    @cristim
    MemberAuthor

    Triage gap: this issue has no priority/severity/urgency/impact/effort/type labels, so PR #1062 could not mirror any. It needs triage. [claude-cc-impl]

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions