The cleanup that killed your vibe coded site's scroll

The scroll worked fine on my laptop and was stone dead on the live site. I'd shipped a small cleanup the night before, the kind that feels like good hygiene, and the next morning the deployed page just sat there refusing to move when you spun the wheel. Nothing in the console. Nothing in the build log. On my machine, with the dev server still warm from the night before, it scrolled like always.

If you're a vibe coder whose site scrolls locally but goes dead after you deploy, and the last thing you did was tidy up some code, the cause is almost always the same. You deleted something that looked like a duplicate and it wasn't one. Text that reads identical is not behavior that's identical, and some of what looks like copy-paste slop is load-bearing resilience that only earns its keep on a timing your dev machine never hits. The line was doing real work. You just couldn't see the work from where you were standing.

why did deleting one line break scrolling on the deployed site?

Because the line I cut was guarding a race, and races don't show up on a warm reload.

The setup was a smooth-scroll provider, the thing that takes over the wheel and makes the page glide instead of jump. In the file, two calls that initialized it sat almost on top of each other, near-identical, the second one looking exactly like the kind of block an AI leaves behind when it regenerates code and forgets to delete the old copy. So on cleanup night I removed the second call. The diff was one line. The tests stayed green. I pushed it and went to bed.

What I didn't know was that the second call wasn't a copy. It was insurance. On a cold production load, the provider's ref sometimes wasn't ready when the first call fired, and the second call re-ran the init once the ref existed. Locally, with everything already in memory and the reload warm, the ref was always ready on the first try, so the second call genuinely did nothing I could observe. The redundancy I deleted was the only thing standing between a working scroll and a dead one, on exactly the load my visitors get and I never do.

why does it work locally and break only on deploy?

Because your dev machine is the most forgiving environment your site will ever run in, and it hides the failures that only appear under a cold, real load.

This is the part that took me too long to internalize about vibe coding a site. When you reload a page on a warm local server, you're testing a version that has already booted once, with fast disk, no network latency, and every ref and cache primed. Production is a cold browser on a real connection loading assets in an order you didn't choose. Timing that's always safe locally becomes a coin flip in the wild. A bug that depends on timing, a race, a load order, a ref that may or may not exist yet, is invisible at exactly the moment you're deciding it's safe to ship. A green local reload is not evidence the change is fine. It's evidence the change is fine on the one machine that will never load your site the way a customer does.

how do I clean up a vibe coded site without shipping the outage?

Treat "looks like a duplicate" as a question, not a verdict, and answer it in the environment that actually runs your site.

The fix was three boring checks I now run every time, and none of them is clever. First, diff behavior, not text. Before you delete a line because it matches another one, ask what it does when the other one fails or fires early. If you can't say, you haven't measured it, you've eyeballed it. Second, cut one thing at a time. A cleanup that removes six obvious duplicates in one commit gives you six suspects when the deploy breaks and no way to bisect. One delete, one deploy, one check keeps the blast radius to a single line. Third, and this is the one people skip, reproduce on the real thing before you trust the cleanup. Push to a preview URL, load it cold in a private window on a phone, and actually use the feature you touched. If the scroll is what you changed, scroll it.

That's the whole discipline, and it's boring on purpose: check where it actually runs, not where it's convenient to run. A vibe coded site can pass every local check and still be broken for every real visitor, and the gap between those two facts is a warm reload that told you what you wanted to hear.

If you're cleaning up an AI-built site and want a second set of eyes before you cut into something load-bearing, /work-with-us.

questions that keep coming up

How do I know if a duplicate is safe to delete? You don't, until you've watched what happens without it under a real load. Delete it on a branch, deploy the branch to a preview, and exercise the path cold in a fresh browser. If nothing changes across a few cold loads, it was probably redundant. If the feature flickers or dies once, it was resilience wearing the costume of a duplicate.

Should I just never delete duplicate code the AI wrote? No. Most of it genuinely is slop, and clearing it out is worth doing. The rule isn't "keep everything," it's "measure before you cut." The expensive mistake is deleting on the assumption that identical-looking means identical-behaving, and learning the difference from a visitor instead of a test.

Why didn't my tests catch it? Because unit tests usually run in the same warm, primed environment your dev reload does. A race that only appears on a cold production load lives in the gap a green suite doesn't cover. That's not a reason to write more unit tests, it's a reason to add one real cold-load check on the deploy before you call a change done.

// part of the ai websites topic

// grab the free starter kit that makes your AI stop forgetting and stop guessing: get it →

// building with AI? the field manual has the structured lessons.

// hitting this on a real build? this is what I fix →