AI Coding Mistakes:4 Ways Claude Sabotages Your Codebase
AI-generated code can work today and quietly fail in month six. The 4 AI coding mistakes to refuse — JSON blobs, enums, any types, silent errors — explained.
AI coding mistakes won't sabotage your codebase with code that breaks. They sabotage it with code that works — for about six months. Claude is confidently wrong all the time, and the dangerous version isn't when it's obviously wrong. It's when it's plausibly wrong: code that compiles, runs, and seems fine, built on a wrong assumption about your data or your business logic.
During eleven months of building FIKR Space, the same four bad patterns kept coming out of the AI. Each one would have created a different, specific kind of pain six months later if I'd accepted it. Here they are in plain English — what Claude proposes, why it looks reasonable, and exactly what it costs you later.
Why AI defaults to mediocre code
Claude has been trained on millions of codebases, and most of them were mediocre. When you don't specify what you want, you get the median codebase output — full of shortcuts and compromises that experienced engineers would never accept. None of these shortcuts fail today. All of them fail later, which is exactly why they survive review by a founder who only checks whether the feature works right now.
Your job isn't to write the code. Your job is to be the senior voice in the partnership — to push back when something doesn't smell right, even when you can't immediately articulate why.
Mistake 1: The JSON blob — a junk drawer instead of a filing cabinet
Claude will suggest storing structured data as a JSON blob — one flexible field that holds everything — instead of a proper table with proper columns. Think of it as tossing your documents into a junk drawer instead of a filing cabinet. The drawer works fine while there are ten documents in it.
This came up for me in week three. Claude proposed storing users' strategic goal data — quarterly goals, OKR status, alignment metrics — as a JSON column on the users table. It would have worked. For about three months. Then I needed to answer a basic business question: show me all users whose Q3 goal completion is below sixty percent. Against a JSON blob, answering that means opening every user's junk drawer and reading everything inside before you can filter — an approach that scaled to fifty users and would have died at five hundred. Fixing it later would have meant migrating six months of customer data and rewriting twelve services. Pushing back in week three cost an extra hour of design conversation. Rebuilding in month six would have cost three weeks.
Mistake 2: Enums — carving today's options in stone
An enum is a field whose allowed values are fixed in advance — like printing your restaurant's menu instead of writing it on a whiteboard. Claude has a strong default toward enums for any field with a small, known set of values: subscription tier, user role, notification type. Each one feels obviously fixed in the moment.
Each one of mine turned out to need new values within a year — a new subscription tier, a new role, a new notification category. And changing an enum in the database requires a multi-step ritual: dropping constraints, recreating the type, updating every row. A lookup table — the whiteboard version — is a normal table that grows by adding a row. The enum locks the column to today's reality; the lookup table accommodates tomorrow's. Same pattern, different default. Push back. Demand the lookup table.
12 weeksYour corporate career was never the planApply to the Solopreneur Accelerator.Apply now →Mistake 3: any types — disabling the smoke alarm
TypeScript's entire job is to catch a whole class of bugs before your users ever see them, by checking that every piece of data is the shape the code expects. When that checking fails on something complex, Claude will sometimes propose marking the data as any — which means "stop checking this." The error goes away. The build succeeds. The feature ships. You've just disabled a smoke alarm, and nothing happens until there's smoke.
This is the most insidious pattern because the symptom is invisible. Six months later, you change something elsewhere in the product, and the type error that should have caught the breakage doesn't — because somewhere upstream an any is silently swallowing the signal. The bug ships to production. You find out from a customer report. Every any you accept now is a future Tuesday afternoon spent debugging a problem the type system was supposed to prevent.
Mistake 4: Silent error swallowing — failures nobody hears
The worst of the four. Claude will sometimes write the equivalent of try { ... } catch (e) { return null } — "if anything goes wrong, say nothing and hand back an empty result" — and call it graceful error handling. That code passes every test you write, because your tests don't deliberately trigger the failure mode.
In production, when the real failure happens, the function returns nothing. Silently. The rest of the system doesn't know anything went wrong. The user sees a blank screen. The error isn't logged anywhere. You don't find out until a customer complains — and even then you can't trace what happened, because no error was ever raised. Fight this every single time: specific failures, handled specifically, logged loudly. The five extra lines of code save you the next outage.
The pattern behind all four AI coding mistakes
| What Claude proposes | Why it looks fine today | The six-months-later pain |
|---|---|---|
| JSON blob instead of proper tables | It works at 50 users | Dies at 500 users; a 3-week rebuild and data migration |
| Enum instead of a lookup table | The values seem fixed | Every new value needs a multi-step migration ritual |
any instead of proper types | The build passes | Type errors stop catching real bugs; you debug in production |
| Silently swallowed errors | "It never throws" | Invisible failures, blank screens, untraceable outages |
The good news: Claude responds well to being challenged. When you say "no, I want this as a separate table, not a JSON blob — and here's why," it will gracefully restructure the code and often improve on what it originally proposed. The model is collaborative. You just have to be the senior voice.
Two habits make the pushback systematic instead of lucky. Brief the AI properly before it builds anything — that's the PRP method. And never let speed substitute for structure — that's the whole lesson of the vibe coding trap. Specify. Push back. Demand the right structure. It costs a little more time per feature, and it buys you a codebase you can still evolve in month twelve instead of one you have to rebuild.
The bookThe Solopreneur RevolutionLuis Gonçalves on building a solopreneur business with AI while employed.Get the book →Frequently asked questions
Why does AI-generated code cause problems months later?
Because AI optimizes for making today's request work, not for how the code evolves. Trained on millions of mostly mediocre codebases, it defaults to shortcuts — flexible blobs, fixed value lists, disabled checks, swallowed errors — that pass every test now and only reveal their cost when the product grows or changes.
How can I spot bad AI code if I can't read code?
Interrogate change and failure, not syntax. Ask the AI: what happens when we need to add a new value here? How would we search this data when we have ten times more of it? What happens when this operation fails — where does the error go? If the answers involve migrations, rewrites, or "it returns nothing," push back.
Should I let Claude make my architecture decisions?
No. Claude is a brilliant implementer and a mediocre architect. Ask it whether something should be a separate table or a JSON column and the answer is usually fine, sometimes bad, occasionally great — and you can't tell which unless you've developed your own architectural taste. The architectural decisions are yours; the implementation decisions are Claude's.
Doesn't pushing back on the AI slow the build down?
A little, per feature — and it's the best trade you'll ever make. Pushing back on the JSON blob cost me an extra hour of design conversation in week three. Accepting it would have cost three weeks of rebuilding in month six, plus migrating six months of customer data.
How trapped are you, really?
Take the Corporate Suffocation Index, the free solopreneur readiness assessment.