Three failing tests, and two copies of the runner

Written August 2026

From building a multi-tenant business platform single-handed — one of four notes on what the work actually taught.

Three tests out of two thousand seven hundred and forty-three began failing with a message about snapshot state not being found. Nothing else failed. The three had nothing in common beyond being the only ones that used snapshots.

The tempting move at that point is to delete the snapshots and regenerate them. It would have worked, and it would have worked for reasons nobody understood, until the next install.

What was actually happening

The repository is a monorepo. Its test setup file lives at the root, because the assertion library it loads is a root dependency — so the setup resolves the root's copy of the test runner, whichever workspace is running.

The package manager keeps one directory per peer resolution, not one per version. The root declared no @types/node; every workspace did. That single difference made the root peer-resolve the runner to a second, distinct installation of the identical version — two directories, same version number, two separate module instances.

Same version, two copies, and the assertion library shared between them.

The assertion library was hoisted and shared. Snapshot matching is registered onto it as a method, bound to whichever runner instance registered last. So the runner set up its snapshot client on one copy while the assertion read the other — and the only tests that could possibly notice were the three that call a snapshot matcher. Everything else in the suite touches neither instance in a way that can tell them apart.

The fix and the guard

The fix was to declare @types/node at the root as well, from the shared catalogue, so every importer peer-resolves to one copy. Three lines of manifest for a failure that read as a bug in the test framework.

The guard matters more. A gate now fails the build if a second runner installation ever becomes reachable, because the next person to hit this — including me, in a year — will see three snapshot failures and no reason on earth to suspect dependency resolution.

What I take from it: when a failure is oddly specific, the specificity is the evidence. Three tests, one feature, everything else fine, is not a flaky suite. It is a narrow question about what those three do that nothing else does — and answering that question is much faster than the shotgun alternative of upgrading things until the red goes away.

What this is from

These come from one project: a multi-tenant business platform for professional firms, where the customers, the projects, the hours, the quotes and the invoices are joined end to end instead of sold as five tools that happen to share a login. Around it sit the public sites, the documentation and the developer tooling it is built with — seven deployed applications and one Postgres database, in a single repository.

It is built and run by one person, outside the hours of a full-time job. That is context rather than a boast, and it is the reason the notes read the way they do: alone, you cannot out-work a mistake, so what matters is leverage — what to automate, what to refuse to claim, and which checks earn back more than the time they cost.

The code is private and none of it is given away here. What these describe is method: how something was measured, what the measurement contradicted, and what changed as a result. A method is worth more read than hoarded — and it is the part nobody can copy without first understanding it.