A hold is not a purchase
If you have ever added a card to a new service and watched a small charge appear and then vanish, you have seen an authorisation hold. Your bank texts you about it in the same breath it uses for real spending, which is how it ended up in our ledger as money you spent.
What a hold is
When a merchant needs to know a card is live before it charges anything to it, it asks your bank to reserve a small amount — often one unit of currency. The bank places a hold. No money moves. Days later the hold is released and the reserved amount comes back.
Holds are also used for a different reason: at a hotel or a fuel pump, where the final amount is not known at the start, the merchant reserves an estimate and settles the real figure later. Same mechanism, different purpose.
The problem for anything reading bank messages is that your bank describes a hold in almost exactly the words it uses for a purchase. Card number, amount, merchant, done. The distinguishing word is buried in the merchant descriptor.
What we got wrong
Our importer was treating GOOGLE TEMPORARY HOLD messages as spending. Three of them turned up in a random sample of one inbox, and when we went looking, the same shape appeared 24 times in total across four years.
Each one added a dollar of spending that never happened. On its own it is small. As a pattern it is worse than small, because it is invisible: the amounts are trivial enough that nobody audits them, and they land in whatever category the merchant name implies, quietly inflating it.
The fix, and what it does not cover
The importer now reads a merchant-labelled hold — temporary hold, temp auth hold, authorisation hold, pre-auth hold — as a pending event rather than a payment, and records nothing.
The ordering matters. That check runs after the one for declined transactions, so a hold your bank refused stays classified as a decline. It runs before the checks that look for settlement words, because a message can carry both and the hold is the more specific fact.
Here is what it still does not catch, and we would rather write it down than let you discover it: a pre-authorisation whose merchant descriptor does not contain the word “hold” still books as spending. Hotels and fuel stations are the common cases. The bank’s own message gives no other signal we can rely on, so short of guessing by merchant category — which would be worse, because it would also delete real hotel and fuel spending — the honest answer is that the transaction editor’s “not a transaction” option is the fix there.
We checked the change the only way that means anything: by re-running the importer over all 9,109 messages in the inbox and diffing the result against the previous run, row by row. Exactly 40 rows changed. Twenty-four were these holds. Sixteen were a separate tax bug. Nothing else moved, which is the point of the exercise — a parser change that improves one shape and silently breaks another is a net loss, and you only find that by looking at every row rather than the ones you were thinking about.
Why we are telling you
This bug had been shipping for a while and nobody complained, because nobody would. A dollar is under everyone’s threshold for caring, which is exactly what makes it worth writing about: the errors that get reported are the loud ones, and the loud ones are not the dangerous ones.
We found it because we started sampling our own import output at random and reading it by hand — the full method, and both error rates it produced, are here.
If you want to check what the app does on your phone rather than take our word for it, there are four ways to do that, and none of them require trusting us.