There Is No Such Thing as an Edge Case. Or is there?
"That's just an edge case."
You've probably heard it after someone finds a weird input, an unexpected state, or a combination of events nobody thought would happen.
Sometimes that's a perfectly reasonable description.
Sometimes it's how a bug gets dismissed.
The interesting question is not whether something is unusual.
It's whether your software needs to handle it.
🔴 The Problem
Imagine you're building a system that accepts a username.
You expect something like:
matej
alex
sarah
Then someone enters:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Is that an edge case?
Probably.
Now imagine someone enters:
admin
That's also a normal-looking username.
But if your system gives special privileges to admin because of an assumption hidden somewhere else, you've got a very different problem.
Neither input looks particularly strange.
The important difference is the assumption your system makes about it.
That's where "edge cases" get interesting.
🟢 The Solution
Instead of thinking:
"How likely is this to happen?"
try asking:
"What does the system need to do if this happens?"
Those are different questions.
A user entering 500 characters might be extremely rare.
But if the application accepts user input, someone eventually will.
A network request taking 10 seconds might be unusual.
But if your application depends on a network request, your code still needs a behavior for it.
A list containing zero items might seem like an edge case.
But if an empty list is a perfectly valid result, it's not really an edge case at all.
It's just another valid state.
const users = await getUsers();
if (users.length === 0) {
showEmptyState();
}
The empty state isn't "special handling" if an empty result is part of the system's normal contract.
It's the contract.
⚡ The "Why"
The phrase "edge case" can make something sound like it belongs outside the main problem.
But software doesn't care how unusual a situation sounds.
It cares whether the situation is inside or outside the behavior you've decided to support.
Consider:
function divide(total, count) {
return total / count;
}
Someone might say:
"What if
countis zero? That's an edge case."
But if count can actually be zero, then the function has a decision to make.
Should it:
if (count === 0) {
return 0;
}
throw?
if (count === 0) {
throw new Error("count must be greater than zero");
}
or produce some other defined result?
The interesting part isn't which decision you make.
The interesting part is that not making a decision is also a decision.
The bug usually appears when the code has an assumption but nobody realized it was an assumption.
🧩 The Boundary Moves
Here's the uncomfortable part.
What counts as an edge case can change.
A system might originally have:
1–10 items
and treat 100 items as unusual.
Then the product grows.
Now customers regularly import 500 items.
The input didn't change.
The system's expectations did.
What used to be an edge case is now normal traffic.
That's why good software isn't built by trying to predict every bizarre thing that could ever happen.
It's built by making important assumptions explicit.
Instead of:
const firstUser = users[0];
renderUser(firstUser);
you might decide that an empty collection is valid:
if (users.length === 0) {
renderEmptyState();
return;
}
renderUser(users[0]);
Now the behavior is deliberate.
The code isn't merely hoping the assumption stays true.
🧠 The Takeaway
There isn't a universal list of edge cases.
An edge case is usually a situation that sits near the boundary of what your system expects to handle.
And those boundaries depend on the system.
So when someone says:
"That's just an edge case."
the useful follow-up isn't:
"How likely is it?"
Ask:
"Is this a state our software is supposed to handle?"
If the answer is yes, it isn't outside the problem.
It's part of the problem.
And if the answer is no, that's worth making explicit too.
Because an edge case isn't necessarily something rare.
Sometimes it's simply an assumption that hasn't been turned into a decision yet.


