
The $47,000 Bug:
That Taught Me to Stop Using ||
A property management company lost thousands due to a single character. Learn why || is dangerous and how ?? saves your production apps.
💡 Pin this to keep notes while reading!
📝 Show Notes & Ideas▼
I was on a call with a developer who’d just spent three weeks debugging a production bug.
Three weeks.
The bug? A single character. Actually, two characters: ||
Here’s what happened: An apartment management company had a tenant portal. Tenants fill out applications. The system tracks how many pets they have. Simple stuff.
const numberOfPets = tenant.numberOfPets || "Data unavailable";
Looks innocent, right?
Except one day, a property manager noticed something weird. Every tenant with zero pets was showing "Data unavailable" in their dashboard. But these tenants had submitted their applications. They’d explicitly written "0" in the pets field.
The support tickets started rolling in. The property managers thought the portal was broken. They started calling tenants manually to re-verify information.
The Fallout
Three weeks of phone calls. Confusion. Frustrated staff. One property manager estimated it cost them $47,000 in wasted labor and delayed move-ins.
All because JavaScript treats 0 as falsy.
The || Operator Has a Dirty Secret
When you write value || fallback, JavaScript doesn't check if value is null or undefined. It checks if value is falsy.
And in JavaScript, "falsy" is a surprisingly long list:
- ✅
null(you probably want to catch this) - ✅
undefined(you probably want to catch this) - ❌
0(this is a real number!) - ❌
""(this is a valid empty string!) - ❌
false(this is a legitimate boolean!)
The || operator can't tell the difference between "we never got this data" and "the user explicitly entered zero."
This is the exact bug I've seen in production systems at least a dozen times in my coaching sessions. It's one of those bugs that's invisible until it isn't.
The Mental Model Shift
Here’s how I want you to think about this:
|| asks:
"Is this value truthy?"
?? asks:
"Does this value exist?"
That’s the Nullish Coalescing Operator (??). Two question marks. And it only triggers on null or undefined, the values that actually mean "nothing is here."
// || treats 0 as "nothing"
const pets = 0 || "No data"; // Result: "No data" ❌
// ?? treats 0 as a valid value
const pets = 0 ?? "No data"; // Result: 0 ✅The ?? operator respects your zeros. It respects your empty strings. It respects your explicit false values. It only falls back when there’s genuinely nothing there.
The Tenant Portal, Fixed
Let’s revisit that apartment management system with the right tool:
const tenant1 = {
name: "John Doe",
cars: null, // Never submitted this field
numberOfPets: 0, // Explicitly said they have zero pets
};
const tenant2 = {
name: "Jane Smith",
cars: 2,
numberOfPets: null, // Forgot to fill this in
};
function getTenantInfo(tenant) {
// Using ?? means we only show fallback text when data is actually missing
const cars = tenant.cars ?? "No car information available";
const numberOfPets = tenant.numberOfPets ?? "No pet data available";
console.log(`Tenant: ${tenant.name}`);
console.log(`Cars: ${cars}`);
console.log(`Number of pets: ${numberOfPets}`);
}
getTenantInfo(tenant1);
// Tenant: John Doe
// Cars: No car information available
// Number of pets: 0 ← Correct! We know they have 0 pets.
getTenantInfo(tenant2);
// Tenant: Jane Smith
// Cars: 2
// Number of pets: No pet data available ← Correct! This field is missing.Zero pets is data. Null pets is the absence of data. The ?? operator knows the difference.
When to Use Which
Here’s my rule of thumb after years of production debugging:
Use || when you want to replace ALL falsy values:
// User display names - empty string should show fallback
const displayName = user.nickname || user.fullName || "Anonymous";
Use ?? when you want to replace ONLY null/undefined:
// Configuration with valid zero/false values
const timeout = config.timeout ?? 3000; // 0 is a valid timeout
const isEnabled = settings.feature ?? true; // false is a valid setting
const port = process.env.PORT ?? 8080; // could legitimately be 0
The question to ask yourself: "Is zero (or empty string, or false) a valid value in this context?"
If yes → use ??
If no → use ||
The Pattern That Keeps Showing Up
In my 700+ coaching sessions, I’ve noticed this bug shows up most often in these places:
- Form inputs - Users enter 0 for quantity fields.
- API responses - Backends return 0 for counts or empty strings for optional fields.
- Configuration - Environment variables that should legitimately be 0 or false.
- Feature flags - Boolean toggles where false is a valid state.
Every one of these gets silently broken by || and silently fixed by ??.
Your Action Item
Go search your codebase for ||. Every time you see it, ask yourself: "What if this value is legitimately zero?"
If the answer makes you uncomfortable, you’ve found a bug waiting to happen. The ?? operator has been in JavaScript since ES2020. It’s not new. It’s not exotic. It’s just underutilized.
Stop treating zero like nothing. Start using ??.
The $47,000 bug was real. The property management company eventually found the fix, a two-character change. But they’ll never get those three weeks back.
You are closer to your goals than you think. Don't let a typo be the reason you stumble.
I was on a call with a developer who’d just spent three weeks debugging a production bug. Three weeks.
The bug? A single character. Actually, two characters: ||
The Setup
Here’s what happened: An apartment management company had a tenant portal. Tenants fill out applications. The system tracks how many pets they have. Simple stuff.
const numberOfPets = tenant.numberOfPets || "Data unavailable";
Looks innocent, right? Except one day, a property manager noticed something weird. Every tenant with zero pets was showing "Data unavailable" in their dashboard. But these tenants had submitted their applications. They’d explicitly written "0" in the pets field.
The Fallout
The support tickets started rolling in. The property managers thought the portal was broken. They started calling tenants manually to re-verify information. Three weeks of phone calls. Confusion. Frustrated staff. One property manager estimated it cost them $47,000 in wasted labor and delayed move-ins.
The Dirty Secret of ||
When you write value || fallback, JavaScript doesn't check if value is null or undefined. It checks if value is falsy. And in JavaScript, "falsy" is a surprisingly long list:
- ✅
null(you probably want to catch this) - ✅
undefined(you probably want to catch this) - ❌
0(this is a real number!) - ❌
""(this is a valid empty string!) - ❌
false(this is a legitimate boolean!)
The || operator can't tell the difference between "we never got this data" and "the user explicitly entered zero."
Danny's Quick Takes:
- →0 is Data, Not Nothing. The
||operator treats 0 as falsy, which destroys valid data like "0 pets" or "0 items in cart". - →Use ?? by Default. The Nullish Coalescing Operator (
??) only triggers onnullorundefined, respecting valid falsy values like0,false, and"". - →The Cost of Invisible Bugs. This bug cost a client $47,000 in manual labor. "It looks fine" is not an engineering standard.
The Bottom Line:
Stop using || for default values. It's a legacy habit that introduces subtle, expensive bugs. Switch your mental model to ??.