A dashboard that shows 0 is making a claim. It is saying: the value is known, and the value is zero.
Sometimes that is true. Nobody cancelled this month, no invoices are overdue, the queue really is empty.
Sometimes it is the software admitting it does not know, in the only way it can — by printing a number that looks like an answer. The reader cannot tell the difference. Neither can the board, the lender, or the client on the other end of the email.
There are four distinct ways a system produces that false zero. They look identical on screen. They have nothing else in common.
1. The error was counted as a quantity
A request goes out for some data. It fails. The failure returns a body — an error message, an HTML page, an empty string. Something reads the length of that body, or counts the items it could parse out of it, and gets zero.
The number is real. It is a count. It is just a count of an error message.
How you get one: ask the system to show a number while its data source is deliberately unreachable, and see whether the screen displays 0 or an error.
If it displays 0, you do not have a number. You have a measurement of the failure.
2. The key was missing and the code had a default
The response arrived. It was valid. It just did not contain the field the code expected — renamed, moved, nested one level deeper, omitted for accounts with no activity.
The code reaches for it, finds nothing, and applies the default it was written with. Almost always that default is 0, because 0 was chosen to stop a crash rather than to be meaningful.
This is the most common of the four, and the most durable — because it only breaks when the shape of the response changes, which nothing monitors.
How you get one: compare the field list of a real response against the fields the code reads. Anything read but not present in every response is a future zero.
3. An exception was caught and swallowed
Something threw. A catch block took it, logged nothing useful, and returned a fallback so the page would render.
The page rendered. It rendered the fallback. Somebody shipped it, because the alternative was an error screen and the screen looked fine.
This one is worse than the other three, because it destroys the evidence. With the first two, the failure leaves traces in the response; here the code has been written to make sure it does not.
How you get one: search the codebase for catch blocks that return a number. Each one is a place where an error becomes a zero.
4. The column was empty and the database filled it in
The query summed a column. There were no matching rows, or every matching row had NULL in that column. The database returned NULL for the sum — which is correct, and means unknown, not zero.
Then an OR 0, a COALESCE(..., 0), or a ?? 0 turned it into a number, because NULL breaks formatting.
Now the sum of nothing renders as 0, and the reader reasonably concludes that spending, revenue or headcount was zero.
How you get one: find an aggregate that can legitimately return NULL and check whether anything downstream coerces it. Aggregates over an empty set are the classic case.
Why they cannot be told apart
On a dashboard, all four produce the same thing: a rendered 0 in a styled box, next to a label, with no indication of provenance.
They diverge only in what they leave behind. One leaves a suspicious body. One leaves a field that is sometimes absent. One leaves nothing at all, by design. One leaves a NULL that was deliberately erased.
That is the whole problem in a sentence: the four failure modes are indistinguishable at the point of display, and only separable at the point of origin. Which means any check that starts from the dashboard is already too late.
What we do not do here
We are not going to walk through fixing all four in this article, and that is deliberate — the fix depends on which one you have, how many places have it, and what the numbers feed into. A generic checklist applied across a real estate does more damage than the zeros did.
What this article is for is narrower: to make you suspect the number, and to give you four places to look.
The one habit worth taking from this
Every number on a client-facing report should be able to answer a question about itself: is this a measurement, or is it the absence of one?
If nobody on the team can answer that for a given number, that number is not evidence. It is decoration that happens to be formatted as evidence — and the moment it reaches a board pack, a lender or a tax filing, it stops being a display problem.
A number you cannot trace to a row is not a fact. It is a claim someone made in a font.