The Half-Applied Batch — Python Bug Hunt

Inspired by every ledger that ever ended a day unbalanced: a batch of postings hits an invalid entry halfway through, the job aborts — and the first half of…

  • Language: Python
  • Layer: Database
  • Difficulty: Medium
  • Concepts: Transactions, Atomicity
  • Modelled on: Ledger systems
  • Visible tests: a valid batch applies fully; a failing batch leaves the ledger untouched
  • Reward: 50 XP for a complete fix

Briefing

Inspired by every ledger that ever ended a day unbalanced: a batch of postings hits an invalid entry halfway through, the job aborts — and the first half of the batch stays applied. Transactions exist so that either everything happens or nothing does.

postings.py mutates as it goes.

Bug report

BUG-ATOMIC · Priority: Critical · Reported by: finance close

apply_batch(ledger, ops) — ops are {"acct", "delta"}:

  • if ANY op references a missing account, or would take any balance below zero, raise ValueError and leave the ledger COMPLETELY unchanged
  • otherwise apply all ops

Observed: a failing 3rd op leaves ops 1–2 applied. The books never balance.

Logs

[ledger] batch failed at op 3/5; partial state persisted

The code as shipped

src/ledger/postings.py (editable)

# Applies a batch of postings to the ledger (acct -> balance).

def apply_batch(ledger, ops):
    for op in ops:
        acct = op["acct"]
        if acct not in ledger:
            raise ValueError("unknown account: " + acct)
        new_balance = ledger[acct] + op["delta"]
        if new_balance < 0:
            raise ValueError("overdraft on " + acct)
        ledger[acct] = new_balance
    return ledger

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