absent and error are different nothings
updated Jul 12, 2026
The private side of this site is end-to-end encrypted, with one small blob holding the passphrase-wrapped master key. On a first visit there’s no keystore yet, so the client offers setup, and setup mints a fresh master key. The trap: to a naive read, “store is down” and “nothing there yet” are the same failed fetch. One transient blip and a routine reload would have offered setup, minted a new key, and permanently orphaned everything sealed under the old one. This got caught in review, which is the only reason it isn’t a bug story.
The fix has two halves. Reads return three states — ok, absent, error — and absent must be proved: a healthy response that positively said “nothing here”. Anything doubtful is an error, rendered as “store unreachable, retry”, never as an invitation to set up. And the write side backs the read side: first-run setup refuses to overwrite, so even a client that somehow concluded “empty” can’t clobber a real keystore.
The contract kept applying. A nightly job read-modify-writes an index, where an error misread as absence would have rebuilt it from empty and erased a year of history. And when I later swapped storage vendors, the distinction had to survive into the vendor’s error body: a 404 naming the missing key counts as absent; a 404 for a missing bucket is a config typo and stays an error.
Most code lets “not found” blur between fact and failure because usually it doesn’t matter. It matters the moment absence triggers initialization. There: prove absence, assume error, and have the write path enforce it too, for the day the read path is wrong anyway.
the hub · warm terminal