"It Works on My Machine" Isn't Proof — It's a Risk Handoff

You've heard it said with total confidence, trusted like it was evidence. It isn't. Here's how a green test suite on one laptop becomes a failed checkout in production — and what reproducibility actually takes.

10 min read
Share:
"It Works on My Machine" Isn't Proof — It's a Risk Handoff

You've heard this sentence said with total confidence. Trusted like it was evidence. It isn't.

"It works on my machine" ends more debugging sessions than it should. It sounds like a conclusion — a result, a green light. But it is not proof of anything except that a particular piece of code behaved a particular way, once, on one specific computer, under conditions nobody wrote down. Everything that made it work might be an accident of that machine. And accidents do not ship.

Let's start where every bug is born: innocent, on a single laptop. This is the story of how a suite of green tests becomes a production incident — and what "done" has to mean if you want to stop it happening.

Key Takeaways

  • "It works on my machine" is not a result — it is an untested assumption about the environment your code ran in.
  • Assumptions don't show up in a diff. Clean editor, zero warnings, and one hardcoded belief about the world can all coexist.
  • The gaps between machines — locale, time zone, seed data, secrets, permissions — are where software quietly disagrees with itself.
  • CI doesn't invent bugs. It runs your code on a clean machine and removes the luck your laptop was silently providing.
  • The sentence survives because it protects ego, not systems: confirmation bias stops the search the moment the code passes.
  • Reproducibility is the real bar. Local green is a start; shared green — the same result everywhere it runs — is the job.

Every Bug Is Born Innocent

Developer running a green test suite on a single laptop

The suite runs. Forty-two tests, all green. Ship it.

Not yet. Because a passing suite tells you that your code did what your tests expected — on the machine your tests happened to run on. It does not tell you which of those passes depended on something true only about that machine. And that is the part no one can see, because assumptions don't show up in a diff. They show up one keystroke at a time.

The editor agrees the code is clean. Zero errors, zero warnings. The linter is happy, the types check, the tests are green. And one field is quietly wrong — one hardcoded assumption about the world, sitting inside code that looks completely healthy. Nothing in the tooling is designed to catch it, because from the tooling's point of view, nothing is broken. It compiles. It runs. It passes. It is also, in a way you cannot yet see, already a bug.


The Assumptions Hiding in a Green Suite

Same repository behaving differently across environments

Same repository, different realities. The code is identical on your laptop, your colleague's laptop, the CI runner, and the production server — but the world around it is not. Locale. Time zone. Seed data. Secrets. Every gap between those environments is a place where machines quietly disagree, and every disagreement is a bug waiting for the right conditions to reveal it.

These are the usual suspects — the assumptions that pass locally and detonate elsewhere:

  • Forgotten secrets in the env file. The API key that lives on your machine and nowhere else. Your tests never notice it's missing, because for you it never is.
  • Seed data that only tests the happy path. Your local database holds the tidy, well-formed records you created. Real data is messier, and the ugly cases you never seeded are the ones that break.
  • Locale assumptions baked into the code. Date formats, decimal separators, currency, string sorting — all quietly correct for your region and quietly wrong for someone else's.
  • A hardcoded tax rate waiting to become a landmine. Correct today, correct in your region, and a silent miscalculation the moment reality moves and the constant doesn't.
  • Logic that only breaks when a real clock ticks. Code that works every time you run it and fails at month-end, across a daylight-saving boundary, or in a time zone that isn't yours.
  • Permissions that production will simply refuse. On your laptop you are effectively an administrator. Production is not so generous, and the operation that "works" locally is denied where it matters.

None of these show up as an error while you're writing them. That's the trap. They are not mistakes the compiler can flag; they are beliefs about the environment, and the environment on your desk agrees with all of them.


CI Removes Your Luck

Continuous integration running code on a clean machine

Enter a clean machine. No laptop luck allowed.

Continuous integration runs the same code on a different machine — one with none of your accumulated conveniences. No secret quietly sitting in a local file. No half-remembered global install. No seed data you shaped by hand. Just your code, your declared dependencies, and a fresh environment that carried none of your assumptions across.

And there it is: expected 12.4, received 10.08. The number that was right on your desk is wrong on the clean machine. It is worth being precise about what just happened, because it is easy to resent CI for it: CI didn't invent this bug. It just removed your luck. The bug was always there, sitting inside a green suite, waiting. All the clean machine did was stop supplying the invisible conditions that were hiding it. That is not CI being difficult — that is CI doing the one job that matters: telling you the truth about your code somewhere other than the one place it was born.


Production Doesn’t Care What Passed Locally

Production dashboard showing a spike in checkout errors

And if a bug slips past CI, the last line of defense is real users, in real time. Production does not care what passed locally.

An 18.4% error rate. 1,204 failed checkouts. Every one of those is a person who tried to give you money and couldn't — because users never run your seed data. They arrive with the messy inputs, the unusual locales, the edge cases, and the exact conditions your laptop never reproduced. Production is where all the assumptions you couldn't see finally meet the world that doesn't share them.

What follows is familiar: the rollback, the war room, the post-mortem. And somewhere in that post-mortem, quietly, the sentence returns — someone points out that it worked fine locally, as if that were a defense. It isn't. It's the beginning of the problem, restated as though it were an alibi.


Why the Sentence Survives

A developer confronting confirmation bias after a failure

If "it works on my machine" is so unreliable, why does it persist? Because it survives for reasons that have nothing to do with engineering. It protects ego, not systems.

Confirmation bias does the rest. The moment the code passes, the search stops. We are wired to stop looking once we get the answer we wanted, and a green suite is exactly the answer we wanted. So the investigation ends precisely where it should have deepened — right at the boundary of what our own machine could tell us. The invisible configuration that made it pass gets forgotten, and when the failure surfaces elsewhere, blame gets handed off like it was proof: not my code, it works for me, must be your environment.

Here is the principle that cuts through all of it: a result that cannot be reproduced is not a result. Science figured this out centuries ago, and software is no different. If the only place your code is known to work is the one machine you can't ship, you don't have a working feature — you have an anecdote. "It works on my machine" is a risk handoff, not proof. It doesn't demonstrate that the software works; it transfers the burden of finding out to CI, to your teammates, or to your users.


What “Enough” Actually Looks Like

Reproducible engineering setup with config as code and CI

So what does enough actually look like? The goal is simple to state: the same code should produce the same result everywhere it runs. That is reproducibility, and it is built out of a handful of concrete, unglamorous practices.

  • One config file, one environment everywhere. The same environment definition drives your laptop, CI, staging, and production — so "different machine" stops meaning "different behavior."
  • Lock files and pinned runtimes. Exact dependency versions and a pinned language runtime, so nobody is silently running different code than anyone else.
  • Clean CI on every push. Every change proven on a fresh machine, automatically, before it merges — not as a formality, but as the actual definition of "it passes."
  • Configuration is code. Secrets, environment variables, and settings are declared, versioned, and reviewed — not improvised on each machine and remembered by whoever set them up.
  • Staging that mirrors production. A real rehearsal environment shaped like the real thing, so the surprises happen somewhere that doesn't cost you customers.
  • Tests for the paths real users actually take. Coverage of the messy, unhappy, edge-case journeys — not just the tidy path your seed data was built to satisfy.

None of this is exotic. It is the difference between hoping your code works and being able to prove it does, on demand, anywhere. That is the whole game.

So rewrite the sentence. Local green is a start. Shared green is the job.


FAQ

Isn’t passing all my tests locally good enough?

Passing tests locally is necessary but not sufficient. A local green suite proves your code did what your tests expected on one machine, under conditions nobody wrote down. It cannot tell you which of those passes depended on something true only about that machine — a secret in your env file, your locale, your permissions, your seed data. Reproducibility means getting the same result on a clean machine that carried none of those conveniences across. That's why CI exists: to run your tests somewhere your luck can't follow.

What’s the single highest-value thing to fix first?

Clean CI on every push, running on a fresh machine. It is the fastest way to convert invisible assumptions into visible failures before they reach users. If you can only do one thing, make "it passes" mean "it passed on a machine that isn't yours." Closely behind that: pin your dependencies and runtime with lock files, so the clean machine is running exactly the code you think it is.

How does staging that mirrors production actually help?

Staging is a rehearsal on a stage shaped like the real one. Bugs that only appear under production-like conditions — real permissions, real data shapes, real configuration, a real clock — surface in staging instead of in front of customers. The closer staging mirrors production, the fewer surprises reach the one environment where surprises cost you money and trust. A staging environment that differs from production in quiet ways just relocates the "works on my machine" problem one step downstream.

We’re a small team. Is this overkill for us?

It's the opposite. Small teams feel a production incident more sharply — fewer people to run the war room, less slack to absorb the rollback, and every lost customer matters more. Reproducibility is not heavyweight enterprise process; at its core it's a config file, pinned dependencies, and automated checks on every push. Those cost a little to set up once and pay back the first time they catch a bug your laptop was hiding. The practice scales down at least as well as it scales up.

Why does “it works on my machine” keep coming back even on good teams?

Because it's a human problem wearing an engineering costume. The moment code passes, confirmation bias tells us to stop looking — the green result is the answer we wanted, so we accept it and move on. And when a failure appears elsewhere, the sentence is an easy way to hand off blame without admitting the search ended too early. The fix isn't just tooling; it's a shared standard that "done" means reproducible, so that a result nobody else can reproduce is treated as unfinished work rather than someone else's problem.

Last updated: August 2026

Ready to Transform Your Business with AI?

Get expert guidance on implementing AI solutions that actually work. Our team will help you design, build, and deploy custom automation tailored to your business needs.

  • Free 30-minute strategy session
  • Custom implementation roadmap
  • No commitment required