Skip to main content
Technology & EngineeringVibe Coding Workflow371 lines

debugging-ai-code

Teaches how to debug code generated by AI tools, covering the unique failure modes of AI-generated code including hallucinated APIs, version mismatches, circular logic, and phantom dependencies. Explains how to read error messages back to the AI effectively, provide minimal reproductions, diagnose when the AI is giving bad fixes, and use systematic debugging approaches on codebases you did not write by hand. Use when AI-generated code is not working and you need to find and fix the issue.

Quick Summary32 lines
Systematic strategies for diagnosing and fixing the unique failure modes of AI-written code.

## Key Points

- Next.js 12.3.4 (Pages Router, NOT App Router)
- TypeScript 4.9
1. **What you did** — the exact command or action
2. **What happened** — the full error message, copied as text
3. **Where it happened** — file path and line number from the stack trace
4. **What you expected** — what should have happened instead
5. **What you already checked** — prevents the AI from suggesting things you tried
- The first line (error type and message)
- The first 2-3 frames that reference YOUR code (not `node_modules`)
- The file and line number
1. Start with the failing code
2. Remove everything that does not affect the bug

## Quick Example

```python
# AI generated this — pandas has no .smart_merge()
df = pd.smart_merge(left_df, right_df, on='id', strategy='fuzzy')

# What actually works
df = pd.merge(left_df, right_df, on='id', how='inner')
```

```
It's not working. Can you fix it?
```
skilldb get vibe-coding-workflow-skills/debugging-ai-codeFull skill: 371 lines
Paste into your CLAUDE.md or agent config

Debugging AI-Generated Code

Systematic strategies for diagnosing and fixing the unique failure modes of AI-written code.


Why AI Code Breaks Differently

AI-generated code fails in ways that human-written code usually does not. Traditional bugs come from logic errors or typos. AI bugs come from the model's training data being outdated, incomplete, or blended across incompatible sources. Understanding these failure categories lets you diagnose faster.


Common AI Failure Modes

1. Hallucinated APIs

The AI invents methods, parameters, or entire libraries that do not exist.

// AI generated this — the method does not exist
const result = await fetch.withRetry('https://api.example.com/data', {
  retries: 3,
  backoff: 'exponential',
});

// What actually works
const result = await fetch('https://api.example.com/data');
# AI generated this — pandas has no .smart_merge()
df = pd.smart_merge(left_df, right_df, on='id', strategy='fuzzy')

# What actually works
df = pd.merge(left_df, right_df, on='id', how='inner')

How to spot it: The error says X is not a function, module has no attribute X, or no such method. Search the official docs for the exact method name. If it does not appear, the AI invented it.

How to fix it: Tell the AI the exact error and specify the library version you are using. Paste the relevant section of the official docs if the AI keeps hallucinating.

2. Version Mismatches

The AI generates code for a different version of the library than you have installed.

// AI wrote Next.js 14+ App Router code
// But you are on Next.js 12 with Pages Router
export default function Page() {
  // 'use client' directive, server components, etc.
}

// Your project actually needs
export default function Page() {
  return <div>...</div>;
}
export async function getServerSideProps() {
  // ...
}

How to spot it: Code looks syntactically valid but uses patterns you do not recognize from your project. Check package.json or requirements.txt for actual installed versions.

How to fix it: Always tell the AI your exact versions up front:

I am using:
- Next.js 12.3.4 (Pages Router, NOT App Router)
- React 17
- TypeScript 4.9

Do not use features from newer versions.

3. Circular Logic and Infinite Loops

AI generates functions that call each other in circles, or retry logic that never terminates.

# AI-generated "retry with fallback" that loops forever
def get_data(source="primary"):
    try:
        return fetch_from(source)
    except ConnectionError:
        if source == "primary":
            return get_data("fallback")
        else:
            return get_data("primary")  # Back to primary — infinite loop

How to spot it: The app hangs, CPU spikes, or you hit maximum recursion depth. Trace the call chain manually: does every path eventually terminate?

How to fix it: Add a max_retries counter or tell the AI explicitly: "The fallback must not recurse back to the primary source."

4. Phantom Imports

The AI imports modules that are not installed, or imports from the wrong package.

// AI imports from a package that sounds right but is wrong
import { createClient } from 'redis';        // correct package
import { createClient } from 'redis-client';  // does not exist

// Or imports a subpath that does not exist
import { helper } from 'lodash/utils/helper';  // no such path

How to spot it: Module not found, Cannot find module, No module named X.

How to fix it: Check npm/PyPI for the actual package name. Tell the AI which packages are already in your project.

5. Confidently Wrong Logic

The code runs without errors but produces incorrect results.

# AI-generated discount calculation
def apply_discount(price, discount_percent):
    return price - (price * discount_percent)
    # If discount_percent=20, this subtracts 20x the price
    # AI confused percentage (20) with decimal (0.20)

# Correct
def apply_discount(price, discount_percent):
    return price * (1 - discount_percent / 100)

How to spot it: Only by testing with known inputs and expected outputs. This is the hardest failure mode because there is no error message.

How to fix it: Write explicit test cases and share them with the AI. "Given price=100 and discount=20, the result should be 80."

6. Merged Incompatible Patterns

The AI blends patterns from different frameworks, languages, or paradigms into one incoherent file.

// AI mixed Express.js patterns into a Next.js API route
export default function handler(req, res) {
  const app = express();  // Wrong — you are already in a handler
  app.use(cors());
  app.get('/api/data', (req, res) => {  // Nested handler — broken
    res.json({ data: [] });
  });
}

How to spot it: The code has redundant layers, framework boilerplate inside framework boilerplate, or patterns that feel like they belong in a different kind of file.


Reading Error Messages Back to the AI

The biggest skill gap in vibe coding is how you report errors to the AI. Bad error reports produce bad fixes.

Anti-Pattern: Vague Error Report

It's not working. Can you fix it?

The AI has no idea what "not working" means. It will guess, change something random, and possibly break something else.

Anti-Pattern: Screenshot of Terminal

A screenshot loses formatting, is not searchable, and the AI cannot always read it accurately. Copy and paste the text.

Effective Error Reporting Template

I ran this command:
  npm run dev

I got this error:
  TypeError: Cannot read properties of undefined (reading 'map')
    at UserList (src/components/UserList.tsx:14:22)
    at renderWithHooks (node_modules/react-dom/...)

The relevant code is in src/components/UserList.tsx lines 10-20.
The `users` prop is coming from a fetch call in src/pages/index.tsx.

I expect `users` to be an array, but it appears to be undefined
on first render before the fetch completes.

The Five Components of a Good Error Report

  1. What you did — the exact command or action
  2. What happened — the full error message, copied as text
  3. Where it happened — file path and line number from the stack trace
  4. What you expected — what should have happened instead
  5. What you already checked — prevents the AI from suggesting things you tried

Trimming Stack Traces

You do not need the entire stack trace. Include:

  • The first line (error type and message)
  • The first 2-3 frames that reference YOUR code (not node_modules)
  • The file and line number
# Too much — the AI gets distracted by framework internals
TypeError: Cannot read properties of undefined (reading 'map')
    at UserList (src/components/UserList.tsx:14:22)
    at renderWithHooks (react-dom.development.js:14985:18)
    at mountIndeterminateComponent (react-dom.development.js:17811:13)
    at beginWork (react-dom.development.js:19049:16)
    ... 40 more lines of React internals

# Just right
TypeError: Cannot read properties of undefined (reading 'map')
    at UserList (src/components/UserList.tsx:14:22)

Providing Minimal Reproductions

When the AI cannot fix a bug from the error alone, give it a minimal reproduction.

What a Minimal Reproduction Is

The smallest possible code that triggers the exact same bug. Strip away everything unrelated.

// Your full component is 200 lines. The bug is in this part:
function UserList({ users }) {
  // BUG: users is undefined on first render
  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  );
}

// Minimal reproduction:
// 1. users prop can be undefined
// 2. .map() is called without a guard
// 3. Crashes on initial render before data loads

How to Build a Minimal Reproduction

  1. Start with the failing code
  2. Remove everything that does not affect the bug
  3. Replace external dependencies with hardcoded values
  4. Verify the stripped-down version still fails the same way
  5. Share the minimal version with the AI

Anti-Pattern: Sending the Entire Codebase

Here is my whole project. Something is broken. Fix it.

The AI will skim, guess, and likely change the wrong thing. Minimal reproductions focus the AI on the actual problem.


Breaking Out of AI Debugging Loops

The AI suggests a fix. It does not work. You tell the AI. It suggests another fix. That breaks something else. You are now in a loop.

The Three-Strike Rule

If the AI has not fixed the bug in three attempts, stop prompting and switch strategies:

  1. Read the code yourself. Trace the data flow manually. The AI may be misunderstanding the architecture.
  2. Search the docs. The AI may be wrong about how a library works. Check the source.
  3. Isolate the layer. Is the bug in the frontend, the API, the database, or the config? Test each layer independently.
  4. Start a new conversation. Stale context from failed attempts pollutes the AI's reasoning. Start fresh with just the error and the relevant code.

When to Add Context vs. Start Over

Add context if the AI is close but missing one piece of information (a type definition, a config value, a version number).

Start over if the AI is going in circles, suggesting the same fix with minor variations, or if the conversation is longer than 20 messages about the same bug.

Manual Debugging Checklist

Before asking the AI again, verify these yourself:

[ ] Is the error message from the current code? (not cached/stale)
[ ] Are all dependencies installed? (npm install / pip install)
[ ] Is the dev server restarted? (some changes need a restart)
[ ] Are environment variables set? (.env file present and loaded)
[ ] Is the correct version of the runtime? (node -v, python --version)
[ ] Is the database running and accessible?
[ ] Are there TypeScript or build errors the AI did not address?

Debugging Strategies by Error Type

Runtime Errors (crashes)

  • Copy the error and stack trace
  • Identify the file and line in YOUR code (ignore framework internals)
  • Check what variable is undefined/null and trace where it should come from

Build Errors (compilation failures)

  • These are usually the easiest: the error tells you exactly what is wrong
  • Common AI causes: wrong TypeScript types, missing imports, syntax from a different language
  • Give the AI the exact error — build errors are unambiguous

Silent Failures (no error, wrong behavior)

  • Add logging at each step to find where actual behavior diverges from expected
  • Write a test with expected input/output and share the failing test with the AI
  • These are the hardest bugs; do not expect the AI to fix them without specific evidence

Configuration Errors (things that should work but do not)

  • AI frequently generates wrong config (webpack, tsconfig, Docker, CI/CD)
  • Compare AI-generated config against the official docs or a known-working config
  • Do not ask the AI to guess at config — paste the docs and ask it to match

Systematic AI Code Review

When the code appears to work but you want to catch hidden bugs before they surface:

Check These AI Blind Spots

// 1. Error handling — AI often catches and swallows
try { riskyOperation(); } catch (e) { console.log(e); }
// Fix: rethrow, return error, or handle meaningfully

// 2. Edge cases — AI tests the happy path
function divide(a: number, b: number) { return a / b; }
// Missing: what if b is 0? What if inputs are NaN?

// 3. Security — AI skips input sanitization
const query = `SELECT * FROM users WHERE id = ${userId}`;
// Fix: use parameterized queries

// 4. Async race conditions — AI assumes sequential execution
const [users, posts] = [await getUsers(), await getPosts()];
// This is sequential. Did the AI mean Promise.all?

// 5. Memory leaks — AI forgets cleanup
useEffect(() => {
  const interval = setInterval(fetchData, 5000);
  // Missing: return () => clearInterval(interval);
}, []);

Anti-Patterns Summary

Anti-PatternWhy It HurtsFix
"It's not working, fix it"AI guesses randomlyProvide error, context, expectation
Pasting full stack tracesAI focuses on irrelevant framesTrim to your code only
Debugging loop past 3 triesDiminishing returns, compounding changesStop, diagnose manually, fresh session
Not checking versionsAI writes code for wrong library versionState versions explicitly
Trusting code that runs without errorsSilent logic bugs are the most dangerousTest with known inputs and outputs
Sending entire codebase for one bugAI loses focusProvide minimal reproduction
Not restarting after config changesStale cache masks the fixRestart dev server, clear caches

Install this skill directly: skilldb add vibe-coding-workflow-skills

Get CLI access →

Related Skills

ai-pair-programming

Teaches effective AI pair programming techniques for tools like Claude Code, Cursor, and Copilot. Covers when to lead versus follow the AI, providing persistent context through CLAUDE.md and .cursorrules files, breaking complex tasks into AI-manageable pieces, using git strategically with frequent commits as checkpoints, and recognizing when the AI is stuck in a loop. Use when working alongside AI coding tools in a collaborative development workflow.

Vibe Coding Workflow325L

maintaining-ai-codebases

Covers the unique challenges of maintaining codebases built primarily through AI code generation. Addresses inconsistent patterns across AI-generated files, refactoring AI sprawl, establishing coding conventions after the code already exists, documentation strategies for AI-built projects, and managing the specific forms of technical debt that AI tools create. Use when a vibe-coded project needs ongoing maintenance or has grown unwieldy.

Vibe Coding Workflow300L

prompt-to-app

Guides the complete journey from an idea to a working application using AI code generation tools. Covers writing effective app specifications, choosing the right tool for the job (Claude Code, Cursor, Bolt, v0, Lovable, Replit Agent), the spec-first approach, iterating on generated code without losing coherence, and managing scope creep during AI-assisted development. Use when someone wants to build an app from scratch using vibe coding.

Vibe Coding Workflow289L

reviewing-ai-code

Teaches how to review, audit, and evaluate AI-generated code effectively. Covers common AI code smells like over-engineering, dead code, wrong abstractions, and hallucinated APIs. Includes security review checklists, dependency auditing, performance review techniques, and strategies for catching the subtle bugs that AI confidently introduces. Use when reviewing code produced by any AI coding tool.

Vibe Coding Workflow307L

scaling-past-vibe

Guides the transition from a vibe-coded prototype to a production-grade application. Covers identifying when the project has outgrown pure vibe coding, refactoring AI-generated code for production reliability, adding tests retroactively to an untested codebase, introducing CI/CD pipelines, establishing code ownership and review processes, and building the engineering practices needed to sustain a growing application. Use when a vibe-coded project is succeeding and needs to become a real product.

Vibe Coding Workflow421L

vibe-coding-architecture

Covers architecture decisions optimized for AI-assisted development. Teaches how to choose frameworks and structures that AI tools work well with, why monolith-first is the right default for vibe coding, how to organize files so AI can navigate them, which abstraction patterns help versus hinder AI code generation, and how to keep complexity within the bounds of what AI can reason about. Use when making technology and architecture choices for a vibe-coded project.

Vibe Coding Workflow402L