Not theoretical. Each one comes with a real receipt — most from this morning.
The bug: Your page tells Google "the official version lives over here" — and "over here" is a 404. Google sees the broken canonical and quietly stops trusting any of the variants. Your traffic just slowly fades.
Why it ships everywhere: Generators that write canonicals don't validate the target file exists. The bug is invisible in normal QA because the page itself loads fine.
The bug: When someone shares your URL on LinkedIn, X, Slack, iMessage, etc — instead of a clean 1200×630 image with your title, they see grey letterbox padding around a tiny default thumbnail. Looks broken. Click-through tanks.
Why it ships everywhere: Adding og:image meta tags is a "later" task. Later never comes. The launch posts go out grey.
The bug: Visitor lands. Visitor has a question. The page has a contact form, a chatbot that says "how can I help?", and a "schedule a demo" button. None of these get answered today. The visitor leaves.
Why it ships everywhere: Founders default to forms because forms feel "professional." Forms convert at ~1%. A real phone or text line that gets answered converts at 10x. Nobody wants to give out a real number.
The bug: Each page exists alone. No "see also," no related links, no breadcrumb back to a parent topic. Google crawls one page, sees no other paths, doesn't index siblings. Your 47 other pages might as well not exist.
Why it ships everywhere: Internal linking is unsexy infrastructure work. It compounds enormously, but it never feels like the priority compared to "ship the next page."
The bug: The page renders on mobile. Looks fine. But the CTA button is below the fold, the contact form is on a different page, the share button doesn't trigger native share, and the phone number isn't tel:-linked. The visitor has to copy-paste to dial.
Why it ships everywhere: Founders test on desktop. Mobile gets a cursory check. Nobody tests "can the visitor actually complete the thing on mobile."
tel: + sms: links on every phone number. Native share button via navigator.share. No copy-paste required for any action.Bug #1 was the worst of them. 12,399 canonicals across 452,076 files all telling Google "my real version lives at /factory/X" where /factory/ never existed. A previous AI session wrote them trying to be clever about crawl budget. The cleverness shipped. The verification didn't.
"It's not the bug you can see that kills you. It's the bug that's been compounding silently for 4 weeks."
Two hours later: self-canonical sweep, 7 source generators patched at root cause, 12,378 files shipped to S3, CloudFront wildcard invalidated, pre-commit guard added so the bug class can't regenerate, re-audit confirms 0 broken.
Recovery clock — frozen for 4 weeks — starts now.
Every indie product has someone who builds the feature. Most don't have anyone who owns the infrastructure layer underneath it — canonicals, OG tags, sitemap, internal mesh, mobile escape hatches, response paths.
The feature is the fun part. The infra is the boring part. So the infra ships broken on launch and stays broken until something visibly bleeds.
By the time something visibly bleeds, you've already lost weeks of trust signal. The bleeding is silent.
This is why every reviewer who looks at 20 indie products finds the same 5 bugs: the bugs aren't products of bad founders. They're products of missing infra ownership.
You can't out-feature broken infrastructure.
The infra layer compounds — for you or against you.
Five things on the launch checklist. Each takes under an hour. All five together = your indie product won't ship pre-broken.
Text the URL. Honest read on which of the 5 bugs your launch is shipping with — before you spend on ads or post on launch day.
Text PJ · 858-461-8054Don't see what you were looking for?
Text PJ a sentence about what you actually need — I'll build you a free custom shareable on the house. No email, no funnel, no SOW.
📲 Text PJ — free shareable