🤖 AI Tools
· 10 min read

My Biggest AI Coding Mistakes in the First Year (So You Don't Repeat Them)


I have been using AI coding tools daily since mid-2025. In that time, I have shipped bugs to production that AI introduced, burned $400 in a single week on API costs, accidentally added a typosquatted npm package, and had to throw away two weeks of work because I followed AI architecture advice without thinking critically.

Every one of these mistakes was avoidable. Every one of them taught me something specific about how to work with AI tools responsibly. I am writing this so you can skip the expensive part and go straight to the lessons.

Mistake 1: Trusting AI-Generated Tests Without Reading Them

This is the one I am most embarrassed about.

I was building a payment processing module. Time pressure was real. I asked Claude Code to generate tests for my payment calculation functions. It produced 24 test cases. They all passed. I committed them, opened a PR, and another developer approved it because “the tests are comprehensive.” We shipped.

Two weeks later, a customer reported being charged incorrectly for a prorated subscription. When I investigated, I found that the AI-generated tests had tested the happy path extensively (full months, standard amounts, single currency) but had not tested the edge case where a user upgrades mid-cycle with a different billing currency. The function had a bug in currency conversion rounding, and none of the AI tests caught it because none of them tested multi-currency scenarios.

The kicker: when I went back and read the test file carefully, several tests were essentially testing the same scenario with different numbers. They looked comprehensive because there were many of them, but they covered a narrow slice of behavior.

What I do now: AI generates the test skeleton and basic cases. I manually add edge case tests for any business-critical logic. I also ask the AI specifically: “What edge cases are not covered by these tests?” It is surprisingly good at identifying its own blind spots when asked directly.

I touched on this when discussing what AI tools are terrible at in testing. The tests pass, but they do not protect you.

Mistake 2: Letting AI Refactor 20 Files at Once

I had a module that needed to be split into three separate services. Twenty files involved. I gave Claude Code the full context and said “refactor this into three modules with clean interfaces between them.”

It did it. Twenty files changed. Tests passed. I committed.

Three days later, bug report one: a webhook handler was calling a function that now lived in a different module, but the import path had been updated incorrectly. The function existed at the new path, but it was a different version with slightly different behavior (the AI had created a wrapper during the refactoring that subtly changed the error handling).

Three more days: bug report two. A background job that processed events was using an in-memory cache that was shared between what used to be one module. After the split, each module had its own cache instance, so the cache invalidation logic stopped working.

A week later: bug report three. A database transaction that used to span two operations within one module was now split across modules without a distributed transaction or saga pattern. Data inconsistency under concurrent writes.

Total time to find and fix all three bugs: four hours of debugging spread over two weeks. The refactoring itself took 15 minutes with AI. But the cleanup took ten times longer.

What I do now: Never let AI change more than five files in a single operation. Break big refactors into stages. After each stage, run the full test suite AND do manual testing of the critical paths. I track the real cost of Claude Code including these hidden costs of debugging AI-introduced issues.

Mistake 3: Using Opus for Everything ($400 in One Week)

During a sprint in March, I was using Claude’s API directly (before the Max plan existed) with Opus 4 for every task. Debugging? Opus. Generating a test file? Opus. Asking what a function does? Opus. Writing a commit message? Opus.

I did not have spending alerts set up. I was in flow state, making great progress, and completely ignoring the cost. At the end of the week, my bill was $412.

The painful realization: at least 60% of those tokens went to tasks that a $0.10/query model could have handled. I was using the most expensive model available to generate boilerplate, answer simple questions, and write documentation. That is like hiring a senior architect to move your desk.

What I do now: Model routing. Simple tasks go to DeepSeek V4 Flash (fractions of a cent per query). Complex reasoning goes to Opus 5. I use OpenRouter to manage this, and I have hard spending limits set per day and per week. I wrote a detailed guide on reducing LLM API costs specifically because of this experience.

The Max plan at $100/month now caps my Claude costs, which helps enormously. But for API usage, spending alerts are non-negotiable.

Mistake 4: Not Checking AI-Suggested Dependencies

This one scared me. I asked Claude to help me add PDF generation to a Node.js service. It suggested a package for handling PDF layouts. The package name was similar to a popular one but slightly different (one character off). I ran npm install without checking.

The package existed on npm. It had downloads (probably from other people making the same mistake, or bots inflating the count). I used it in my code, pushed to a branch, and only caught it during PR review when a colleague said “I have never heard of this package, did you mean [correct-package-name]?”

I checked the package source. It was not malware in this case, just a near-empty wrapper that re-exported the real package. But it could have been. Typosquatting on npm is a real attack vector, and AI tools will suggest package names they have seen in training data without verifying they are the canonical, trustworthy version.

What I do now: For every AI-suggested dependency, I verify: (1) it exists on npm/pypi/etc., (2) it has meaningful download counts, (3) the GitHub repo is real and active, (4) the name matches what I expect. This takes 30 seconds per package and has prevented at least two more suspicious suggestions since then.

Mistake 5: Skipping Code Review Because “AI Wrote It”

This is the most insidious mistake because it is a gradual habit, not a single event.

Over time, I developed a trust relationship with AI output that was not warranted. If Claude Code made changes and the tests passed, I would commit without carefully reading the diff. “The AI knows what it’s doing, and the tests pass.” This is the exact same logic that makes people skip code review for senior developers, and it is wrong for the same reasons.

The bugs I missed during this period were all logic errors. Technically correct code that did not match the intended behavior. A sort function that was ascending when it should have been descending. A cache TTL that was in seconds when the rest of the system used milliseconds. A feature flag check that was inverted.

These are exactly the kinds of bugs that tests do not catch because the tests were written with the same misunderstanding.

What I do now: I review every AI-generated diff with the same rigor I would apply to a junior developer’s PR. The AI is very productive and quite capable, but it does not understand intent. I am the only one who knows what the code should do. This review habit is part of why my time savings are 8.5 hours net rather than 10.5 gross.

Mistake 6: Using AI for Architecture Decisions on a New Project

In April, I started a new internal tool. Instead of thinking through the architecture myself, I asked Claude Code to suggest the structure, patterns, and tech stack based on the requirements I described.

It suggested: Next.js with a serverless backend, Prisma ORM, tRPC for type-safe API calls, deployed on Vercel. Perfectly reasonable choices that would look great in a conference talk.

The problem: our team had zero experience with tRPC, our infrastructure was on AWS (not Vercel), and the “serverless backend” did not work with our VPN-only internal databases. I spent two weeks building this before realizing I was fighting the architecture at every step.

I threw it away and rebuilt with: Express (which we all know), deployed on ECS (which we already run), with a simple REST API. Boring, but it matched our team and infrastructure. Built in three days what had taken two weeks with the AI-suggested architecture.

What I do now: AI can list architectural options and their tradeoffs. It cannot make the decision because it does not know your constraints. I always make architecture decisions myself, then use AI to implement them. For a longer discussion of this limitation, see my article on what AI tools are terrible at.

Mistake 7: Running Agents Without Cost Limits

One night I left an Aider session running with a complex refactoring task. I had connected it to Claude’s API without a spending cap. I went to bed thinking it would either complete or error out.

Instead, it got stuck in a loop. It would make a change, run tests, see a failure, try to fix it, introduce a new failure, try to fix that, and so on. Each iteration consumed tokens. By morning, the bill was $89 for a task that should have cost about $5.

The code was also in a terrible state. Dozens of conflicting changes layered on top of each other, each one a failed attempt at fixing the previous attempt. I had to git reset and start over anyway.

What I do now: Every AI tool that uses API billing has a spending limit configured. OpenRouter makes this easy with per-key limits. For Claude Code, I use the Max plan which caps at $100/month. For Aider, I set the --max-cost flag. No exceptions, no “just this once” overrides.

I also never leave an agent running unattended on a usage-based plan. If it needs to run overnight, it runs on a flat-rate subscription or not at all.

What I Do Differently Now (The System)

After a year of mistakes, here is my actual process:

  1. Model routing by task complexity: Simple tasks get cheap models (DeepSeek V4 Flash, local Ollama models). Complex tasks get Opus 5. Nothing in between uses the expensive model.

  2. Batch size limits: Maximum five files per AI operation. Larger refactors get broken into stages with manual review between each stage.

  3. Mandatory review: Every AI-generated diff gets read line by line. No exceptions, no matter how simple it seems. This is the tax you pay for speed.

  4. Dependency verification: 30 seconds of manual checking per AI-suggested package. Non-negotiable.

  5. Spending alerts: Daily and weekly caps on every API key. If I hit 80% of my weekly budget by Wednesday, I switch to local models for the rest of the week. Details in my cost management guide.

  6. Architecture decisions stay human: AI implements, I decide. The thinking work is mine. I use the best AI tools for execution, not strategy.

  7. Test authorship for critical logic: AI writes the test scaffold. I write assertions for anything involving money, authorization, or data integrity.

These rules feel obvious in hindsight. They were all learned through pain. I hope reading about my pain saves you some of your own.

FAQ

How much money did these mistakes cost you total?

Roughly $600 in direct API costs (the $400 week plus the $89 overnight bill plus various smaller incidents) and probably 60 hours of wasted time from the architecture rewrite, bug hunting, and general over-trust. The time cost was far more expensive than the money.

Did any of these mistakes affect production users?

Yes. Mistake 1 (the payment bug) and Mistake 5 (the accumulated logic errors from skipping review) both resulted in production bugs that affected users. None were catastrophic, but they were embarrassing and avoidable.

Are newer models less likely to cause these issues?

Somewhat. Opus 5 makes fewer logical errors than Opus 4 did. DeepSeek V4 is better at respecting constraints than V3. But the fundamental issues (AI does not know your intent, AI does not understand your specific constraints) remain. Better models reduce frequency but do not eliminate the need for review.

What is the single most important habit to prevent AI coding mistakes?

Read the diff. Every time. The moment you stop reading what AI generates, you start accumulating invisible bugs. It takes two to five minutes per change. It is the cheapest insurance you can buy.

Should these risks make developers avoid AI tools?

Absolutely not. The net productivity gain is massive even after accounting for all these mistakes. The correct response is not avoidance but discipline. Use the tools aggressively, review the output carefully, and set hard limits on spending. The developers who struggle are not the ones using AI tools; they are the ones using AI tools without guardrails.