{
  "id": 14402737,
  "title": "Two of my AI agents shared one budget file and a charge vanished. Here is the SQLite fix",
  "url": "https://urgent.news/2026/10/14/two-of-my-ai-agents-shared-one-budget-file-and-a-charge-vanished-here",
  "topic": "ai",
  "section": "AI",
  "published": "2026-10-14T08:26:06.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/renev3408/two-of-my-ai-agents-shared-one-budget-file-and-a-charge-vanished-here-is-the-sqlite-fix-3ihg"
  },
  "original_language": "en",
  "account": "Two AI agents were using the same budget file simultaneously. Each agent successfully passed the check and wrote their own changes back, causing one charge to vanish. This occurred because the load, check, and save operations were not atomic. To fix this issue, the code demonstrated how to use SQLite's atomic updates to reserve funds first in one statement, then commit the change. By doing this, two agents cannot both slip under the budget cap. The fix includes a reserve function that ensures the cap is not exceeded and a refund function that only refunds the amount if the reservation never took place. Additionally, the code includes a BudgetExceeded exception to catch over-budget errors and a guarded_call function that reserves funds before making a call and refunds them if the call fails. To prevent runaway retries, a FailureBreaker class tracks consecutive failures and raises an exception after a set number of attempts. The setup uses dollars as the main stop condition, with consecutive failures as an additional safeguard.",
  "summary": "A reader pointed out a bug in a budget guard I posted: two agents can read the same budget_state.json , both pass the check, both write back, and one charge disappears. They were right. Here is why it happens and a fix you can copy. The bug: load, check, save is not atomic import json def charge ( amount , cap , path = \" budget_state.json \" ): state = json . load ( open ( path )) # agent A and…",
  "key_points": [
    "Two AI agents simultaneously used the same budget file, causing one charge to vanish.",
    "SQLite atomic updates were used to reserve funds first, then commit the change."
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}