reject_pending_entry bypasses FavaClient write lock #23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bug
reject_pending_entry(views_api.py:2860-2956) mutates the Beancount source file by calling Fava'sPUT /api/sourcedirectly withhttpx.AsyncClient, bypassingFavaCliententirely. It does not acquireFavaClient._write_lock.Every other mutation path in the codebase goes through
FavaClientand takes the lock (add_entry,update_entry_source,delete_entry,add_account). This is the only writer that doesn't.Failure mode
Concurrent reject + add (or two concurrent rejects against entries in the same file) race on the file's
sha256sum. Fava's optimistic-CC will 412 the loser; the call site has no retry/queue. Net result: the admin's reject silently fails with no recovery path. Hasn't bitten in practice because rejects are rare and admin-driven, but it's a real correctness gap independent of any architectural improvement.Fix
Two viable shapes:
/api/sourcecall inasync with fava._write_lock:to close the lock gap without changing the data model.FavaClient.add_entry, which already takes the lock. Lock gap disappears as a side-effect of consolidation.If #2 is imminent, do this fix as part of it. If #2 slips, ship (1) standalone — this is a bug today, half a day of work, and it should not be hostage to a larger refactor's timeline.
Scope
views_api.py:2913-2954— the directhttpxblock inreject_pending_entry.Half-day estimate for the stopgap.