A Bohrbug is a software defect that is entirely deterministic, perfectly reproducible, and stubbornly present regardless of observation, environment, compiler mood, or phase of the moon. It crashes every time, on every machine, with the same input, in the same way, at the same line.
Named after Niels Bohr’s atomic model — in which electrons follow fixed, predictable orbits — the Bohrbug is the Heisenbug’s boring twin. Where the Heisenbug vanishes when you attach a debugger, the Bohrbug sits patiently in the same place it has always been, waiting for someone to come and look at it. It does not hide. It does not shift. It is the honest bug.
This does not make it easy to fix.
“The Bohrbug is the bug that respects you enough to crash the same way twice. This is somehow worse.”
— The Caffeinated Squirrel, debugging a null pointer for the third consecutive sprint
The Paradox of Visibility
The Bohrbug’s defining characteristic — total reproducibility — creates an assumption that it should be trivial to fix. Management sees a bug that crashes on every run and concludes that the fix is obvious. The developer sees a bug that crashes on every run and knows that the fix requires rewriting a module that seven other modules depend on, one of which was written by someone who left the company in 2019 and whose code comments are in a language nobody on the team speaks.
The Bohrbug is easy to find. It is right there. It has always been right there. The difficulty is not locating it but surviving the surgery required to remove it.
“A Bohrbug is a known address in a bad neighborhood. You know exactly where it is. You are not going there alone.”
— The Lizard, declining to refactor a 2,000-line switch statement
Relationship to the Heisenbug
The Bohrbug and the Heisenbug are complementary phenomena. The Heisenbug disappears when observed. The Bohrbug remains when ignored. The Heisenbug is a ghost. The Bohrbug is furniture.
Teams that suffer from Heisenbugs long for the simplicity of a Bohrbug. Teams that suffer from Bohrbugs long for the Heisenbug’s occasional mercy of simply going away.
Neither team is happy.
The @Skip Memorial
In mature codebases, Bohrbugs are often commemorated with a failing test that has been annotated @skip, t.Skip(), or // TODO: fix this since an earlier geological era. The test documents the bug perfectly. The test reproduces the bug perfectly. The test is never run.
This is the Bohrbug’s natural habitat: known, documented, reproducible, and absolutely not prioritized.
“I have calculated that the average Bohrbug persists for 847 days between first detection and fix. The median is ’never.’ I find this… relatable.”
— The Passing AI, contemplating permanence
Measured Characteristics
- Reproducibility rate: 100% (by definition)
- Average time from detection to fix: 847 days (median: ∞)
- Tests marked @skip that document Bohrbugs: ~40% of all skipped tests
- Developers who say “I’ll fix it next sprint”: 100%
- Developers who fix it next sprint: 8%
- Modules that depend on the code containing the Bohrbug: always more than expected
- Stack traces that are identical across every reproduction: all of them
