Debug the runtime
Verify dependencies and build output
Compare lockfile, runtime version, installed dependency tree, generated artifact, and source revision.
10 minute lesson
You fixed the bug, deployed, and the error is still there. Before doubting the fix, doubt the artifact: a local source fix does not help if production runs another artifact, runtime, or dependency resolution. This whole class of “but I fixed that!” bugs is an identity problem — the code you are reading is not the code that is running.
Record deploy identity
Capture the same four facts in every environment. Record deploy identity:
node --version
npm ls --depth=0
git rev-parse HEAD
shasum -a 256 dist/app.js
Each line closes one gap. node --version catches runtime drift: code using a newer API works on your Node 24 and throws on the server’s Node 18. npm ls --depth=0 shows the dependency tree as installed, not as declared — a missing lockfile can resolve different versions from the same package.json on different days. git rev-parse HEAD pins the source revision. The shasum of the built artifact is the ground truth: two machines with the same hash run the same bytes.
Compare, don’t assume
Compare the working and failing environments line by line:
local: v24.2.0 abc123f dist/app.js sha256 9f2c...
prod: v24.2.0 abc123f dist/app.js sha256 4a71...
Same runtime, same commit, different artifact hash. Everything narrows to the build step: a stale build cache, a CI job that built another branch, or a deploy that copied an old dist/. Rebuild from a clean checkout and verify the deployed hash matches the tested artifact. If the hashes now agree and the bug persists, the fix itself is wrong — also useful to know.
The lockfile deserves a specific check: confirm it is committed, and that deployment installs with npm ci rather than npm install. npm ci installs exactly what the lockfile says and fails loudly when the lockfile and package.json disagree, which is exactly the noise you want.
Keep the variables still
Do not run broad dependency upgrades during diagnosis. An npm update mid-investigation changes dozens of variables at once, can erase the original evidence, and may fix the symptom while hiding the cause. Pin everything, find the bug, then upgrade deliberately with its own tests.
Lesson completed