Home All posts →

PocketBill Blog

The Number Was Never Wrong

Published 2026-10-10 · PocketBill team

I spent a day chasing garbage text through an app, and every suspect I checked was innocent. The data was right, the API was right, the header was right. What was broken was the container. Then I wrote one line of cleanup code that quietly emptied five files, which is the same lesson from the other direction.

The nine ninety-nine I couldn't place

On March's statement there was a charge for 9.99 dollars. I stared at it for a good half minute before I could name the app it belonged to — something I installed in February, opened twice, and never thought about again. The number was correct. The bank was correct. The only thing that had failed was the place I was keeping it, which was my memory.

That gap between a correct record and not knowing what it means is the whole reason PocketBill exists: a local-first tracker with nothing to sign in to, where the charge and the reason it's there live in the same place. I did not expect that same gap to eat an entire day of my week in the code.

Three suspects, none of them guilty

A settings screen in one of my projects had started showing garbage instead of Chinese text — the kind of mojibake that looks like a different alphabet entirely. My first suspect was the API. I curled it directly, checked the network panel, and the characters came back perfect. Innocent.

Suspect two was the response header. It was missing a charset declaration, so I wrote a custom JSON response class, forced the header in, restarted everything. Still garbage. The header was a reasonable guess and it was wrong. Suspect three was the actual answer: the file the text lived in had been saved in an older encoding, and the build tool read it as UTF-8 anyway. Every layer of data was correct. The container was broken, and I'd spent hours interrogating the wrong ones.

The line I wrote that emptied five files

While I was in there I ran a little script to strip the byte-order mark off some files. One line: open the file for writing, then read it. Opening for writing truncates the file to zero bytes before you read a single byte, so I read nothing and wrote nothing, and five Python files came back empty. Git had them. My afternoon didn't.

The lesson isn't really about encodings. It's that order of operations is not a detail, and that the thing you're certain about is usually the thing you should check first. Both times, I was staring at a number that was fine and a system that had quietly stopped meaning what it said.

Two folders, one truth

The last surprise was two copies of the same project on the same machine, one of them forty-seven files behind. Two places to look, one of them lying, and nothing on screen to tell you which. I fixed it by deleting the stale one, which is the only reliable fix there is.

That's why PocketBill doesn't sync anything anywhere by default. One record, on your device, that means exactly what it says — so the next time a 9.99 charge shows up, you don't have to spend half a minute guessing what you were thinking in February.

indie-devdebugginglocal-firstpocketbill
Track it once, see it forever.
Add your first subscription or expense in PocketBill — no account required.