Six months of adding tools to my site, one page router file, and a lesson about the difference between "works on my machine" and "exists in version control." The setup DukoTools just went from 112 to 138 tools. Most of that work happened gradually, build a component, wire it into the router, test locally, move to the next tool. Standard incremental development. What I didn't do consistently: commit each tool as a complete, atomic unit the moment it was wired in. The bug While fixing an unrelated i18n issue, I edited the shared tool page router, src/app/[locale]/tools/[slug]/page.tsx ,to add hreflang gating logic. The edit was correct. The file compiled locally. I committed it. The next Vercel deploy failed: The router file already had import statements and switch cases for 7 tools whose actual component files had never been committed to git. They existed only on my local machine. Locally, the build succeeded because the files were sitting right there on disk. On a clean Vercel clone, they didn't exist, and the build died at the first missing import. I hadn't noticed because I was editing that file for a completely unrelated reason. The broken references were already there before I touched it, my edit just happened to be the commit that finally shipped them to main. The actual root cause The router file was being treated as a single artifact. In reality, it's a shared surface that multiple, independently-completed features all touch. Every tool added an import line and a switch case to the same file, but the component itself, its tools.ts entry, and its translations were separate, independently-committable units that didn't move in lockstep. Nothing enforced that "this router line" and "this component file" ship together. So eventually they didn't. The fix, and the verification that mattered more than the fix The fix itself was small: remove the 14 orphaned lines (7 imports + 7 switch cases) referencing uncommitted components. The verification is the part worth stealing: git stash push -- page.tsx # revert to committed state npm run build # does it fail the same way without my changes? git stash pop # restore Confirming the bug existed before my edit — not because of it — mattered more than the fix itself. It's the difference between "I broke this" and "I finally exposed something that was already broken." The stronger verification, once the fix was ready: git clone <repo> /tmp/clean-test --branch fix-branch cd /tmp/clean-test npm install npm run build # exit code 0, in an environment with zero local state A fresh clone into a temp directory, with no leftover node_modules, no stray local files, nothing my dev machine happened to have lying around, the closest local simulation of what Vercel's build environment actually sees. npm run build passing locally never proved that. Only a clean clone does. What generalizes A shared file (router, config, registry) is only as reliable as the discipline around what's allowed to reference what. If feature A can add a line to a shared file before feature A is fully shipped, you've built a landmine, not a bug. "Builds locally" and "builds from a clean clone" are different claims. Local builds see your entire filesystem, including whatever you forgot you had lying around. CI/deploy only sees git. Before fixing a bug, prove it predates your change. git stash, rebuild, compare. It's five extra minutes and it's the difference between confidently shipping a fix and guessing you didn't make things worse. Ship features as atomic units across every file they touch — component, registration, content, translations together, or not at all. Partial commits of a multi-file feature are how this bug is born. Status 138 tools, live, verified via clean-clone build. The 7 previously- orphaned tools are now fully committed as complete units, component, registration, and content shipped together in one commit, not spread across a week of half-finished edits. Building DukoTools solo — 138 free tools and counting, apparently also collecting deployment lessons at a similar pace.