The Optimistic Lock That Wasn't — Python Bug Hunt

Inspired by the lost-update bugs behind countless "my changes disappeared" tickets.

  • Language: Python
  • Layer: Database
  • Difficulty: Medium
  • Concepts: Concurrency, Versioning
  • Modelled on: CMS platforms
  • Visible tests: a matching version applies and bumps; a stale version is rejected
  • Reward: 50 XP for a complete fix

Briefing

Inspired by the lost-update bugs behind countless "my changes disappeared" tickets. Two editors load version 4; both save; the second silently erases the first. Optimistic locking exists precisely to stop this — if anyone actually checks the version.

optimistic.py doesn't.

Bug report

BUG-LOST-UPDATE · Priority: High · Reported by: CMS team

update_row(row, expected_version, changes):

  • row["version"] != expected_version -> raise ValueError("conflict")
  • otherwise apply changes and INCREMENT row["version"]

Observed: stale writers win, and version never moves off 1.

Logs

[cms] doc 88 saved by editor A (v4) then editor B (v4) -> A's edits gone

The code as shipped

src/store/optimistic.py (editable)

# Optimistic-concurrency row update.

def update_row(row, expected_version, changes):
    for key in changes:
        row[key] = changes[key]
    return row

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Python bug hunts.