Skip to content
BACK TO JOURNAL
Engineering5 MIN READ · JULY 2026

Why Software Isn't Finished When
the Code Works

'It works' is a claim about the happy path. Users don't live on the happy path.

Fojan Studio

The demo goes well. The tests are green. The feature does the thing it was built to do, and there's a moment, every engineer knows it, where it feels finished. That feeling is the trap. Because 'the code works' is a much narrower claim than it sounds.

It usually means: it works when the input is valid, the network is fine, the user does what I expected, and I already know how it's supposed to go. That's the happy path. It's real, and it's maybe half the work.

The other half is everything that goes slightly wrong

Users don't arrive with clean input and full context. They paste the wrong thing, lose signal halfway through, double-click the button, land on the screen with no data yet, and hit the one combination you didn't test. The difference between software that works in a demo and software that works in the world is almost entirely in how it handles those moments.

  1. 01Errors. Does the failure explain itself, or dump a stack trace at a stranger? Nielsen's heuristics put error prevention and plain-language recovery near the centre of usable software for a reason.
  2. 02Empty states. The first time someone opens the feature, there's no data. That screen is the one you designed last and they see first.
  3. 03Latency. The code that's correct at 50 milliseconds can be unusable at three seconds. Correct and usable aren't the same property.
'Done' is not when the code produces the right answer. It's when the person using it can't easily produce the wrong outcome.

Working in isolation is not working in production

There's a second gap. Code that works on your machine hasn't yet met real traffic, real data volumes, or real concurrency. This is the whole premise behind treating production as its own bar to clear, a feature isn't finished when it passes tests, it's finished when it behaves under the conditions it'll actually run in. The migration that's fine on ten rows and locks the table on ten million. The query that's instant until the table is real. These aren't edge cases. They're the destination.

Define done before you feel done

The cure isn't heroics. It's deciding, up front, what finished actually means for a given change, and writing it down. What are the error paths? What does the empty state say? What happens at 10x volume? What does the user see when the thing they wanted isn't there? If you can't answer those, the feature isn't done. It's demoable, which is a different and much cheaper thing.

The green test suite is a floor, not a finish line. It tells you the code does what you told it to. It says nothing about whether you told it the right things, or about the person on the other side, who is about to do something you didn't expect.