Debugging AI-generated code is a unique challenge. You are looking at code you did not write, understanding logic you did not design, and fixing bugs in patterns you did not choose. Traditional debugging skills still apply, but you need a different approach.
Here is the uncomfortable truth about AI debugging: Claude Code almost never fails because it lacks intelligence. It fails because it lacks visibility. You have browser dev tools, console logs, network requests, and actual behavior on your screen. The AI has code files. That is it.
The key to debugging with AI is giving it the visibility it needs.
The Four-Step Debugging Method
Every debugging session with AI follows the same pattern. Reproduce, isolate, fix, verify.
Step 1: Reproduce. Give AI the exact error, the exact steps, and the exact environment. Do not summarize. Copy the full stack trace, the full error message, and the full command that triggered it.
Step 2: Isolate. Let AI trace through the code to find the root cause. Not the symptom — the cause.
Step 3: Fix. Apply the fix. Let AI explain why the fix works.
Step 4: Verify. Run the tests. Check that the fix solves the problem and does not break anything else.
Skipping any step leads to band-aid fixes that hide the real problem.
Paste the Error, Get the Fix — The Right Way
The most common debugging flow is pasting an error into AI. Most developers do this wrong.
Bad approach:
I am getting a TypeError. Fix it.
Good approach:
I am getting this error when running npm test:
FAIL src/services/__tests__/userService.test.ts
● createUser › should hash password before saving
TypeError: Cannot read properties of undefined
(reading 'hash')
14 | const passwordHash = await bcrypt.hash(
15 | password,
> 16 | SALT_ROUNDS
| ^
17 | );
at Object.<anonymous>
(src/services/userService.ts:16:5)
The test was passing before I refactored the import
statements. I changed from CommonJS requires to ESM
imports in this file.
The bcrypt import is: import bcrypt from 'bcrypt';
The second approach gives AI:
- The full error with stack trace
- The exact line where it fails
- What changed before the error appeared
- The relevant code context
Claude Code response to this prompt:
The issue is with the default import. The
bcryptpackage uses CommonJS exports, so when you import it as ESM, the default import does not get the module’s exports correctly.Change the import from:
import bcrypt from 'bcrypt';to:
import * as bcrypt from 'bcrypt';Or add
"esModuleInterop": trueto your tsconfig.json if it is not already there.
This is a real, root-cause fix — not a band-aid. The AI diagnosed the ESM/CJS interop issue because the developer mentioned the refactor.
Reading Stack Traces with AI
Stack traces are gold for AI debugging. The AI can trace through multiple files and find where things went wrong.
Prompt pattern:
Here is the full stack trace from a crash in production:
[paste the entire stack trace]
Walk through the stack trace from bottom to top.
Explain what each function call is doing.
Identify where the data could have become corrupted
or null.
AI is excellent at this because it can read all the files in the call stack. A human might need to open 5 files and trace the flow manually. AI does it in seconds.
When to give more context:
- If the stack trace references external libraries, tell the AI which versions you are using
- If the error only happens under certain conditions, describe those conditions
- If you have logs from before the crash, include them
Common AI Code Bugs to Watch For
AI coding tools produce specific types of bugs consistently. Knowing these patterns helps you find them faster.
Race Conditions
AI often generates async code that looks correct but has timing issues.
// AI-generated code with a race condition
async function updateUserProfile(userId: string, data: ProfileData) {
const user = await getUser(userId);
const updatedUser = { ...user, ...data };
await saveUser(updatedUser);
return updatedUser;
}
The problem: if two requests call this function at the same time, the second request overwrites the first one’s changes. AI rarely generates optimistic locking or atomic updates unless you ask for it.
Detection prompt:
Check this function for race conditions.
It handles concurrent requests from multiple users.
Could two parallel calls corrupt the data?
Null and Undefined Handling
AI frequently generates code that assumes data exists when it might not.
// AI-generated code with null issue
const userName = user.profile.displayName.toUpperCase();
If profile is null or displayName is undefined, this crashes. AI models generate this pattern constantly because it is the most common pattern in training data.
Detection prompt:
Review this code for null/undefined access.
Assume any database lookup, API call, or optional
field could return null. Mark every unsafe access.
API Hallucinations
This is unique to AI-generated code. The AI references functions, methods, or properties that do not exist. Over 42% of code snippets from AI tools contain some form of hallucination, including non-existent APIs.
# AI-generated code using a non-existent API
import pandas as pd
df = pd.read_csv("data.csv")
result = df.smart_merge(other_df, on="id") # smart_merge does not exist
The code looks correct. It follows naming conventions. But smart_merge is not a pandas method. The AI invented it based on patterns.
How to catch hallucinations:
- Run the code. Non-existent methods throw errors immediately.
- Check imports. If AI adds a new dependency, verify it exists on npm/PyPI.
- Use your IDE. Hover over methods to check they exist. TypeScript and other typed languages catch most hallucinations at compile time.
- Ask AI: “Does the
smart_mergemethod exist in pandas? Link to the documentation.”
Stale Patterns
AI was trained on code from different time periods. It sometimes generates deprecated patterns or uses old API versions.
// AI-generated code using deprecated React pattern
class UserProfile extends React.Component {
componentWillMount() {
this.fetchData();
}
}
componentWillMount has been deprecated since React 16.3. AI still generates it because there are millions of examples in its training data.
Prevention: Add to your CLAUDE.md or context file:
## Common Mistakes to Avoid
- Do NOT use class components. Use function components with hooks.
- Do NOT use componentWillMount. Use useEffect.
- Do NOT use moment.js. Use date-fns or Temporal API.
The Rubber Duck Technique with AI
Rubber duck debugging is explaining your code line by line to find the bug. AI is the best rubber duck ever — it actually responds.
Prompt:
I have a bug where users are logged out randomly after
about 30 minutes. I think it is a token expiration issue
but I am not sure.
Let me explain what I think happens:
1. User logs in, gets a JWT with 1 hour expiration
2. Frontend stores it in localStorage
3. Every API request sends it in the Authorization header
4. The auth middleware checks the token
5. But somehow users get 401 after ~30 minutes
Can you look at the auth middleware in src/middleware/auth.ts
and the token generation in src/services/authService.ts?
Tell me what could cause a 30-minute expiration instead
of 1 hour.
By explaining what you think happens, you help the AI focus its search. If your understanding is wrong at step 3, the AI can catch it.
Common findings from this technique:
- The token expiration is set in seconds but the code uses milliseconds
- The server clock is different from the client clock
- A refresh token mechanism is failing silently
- A load balancer is routing to a server with a different JWT secret
When to Revert and Re-prompt
Sometimes the AI fix makes things worse. Here is when to stop debugging and start fresh.
Revert when:
- The AI has attempted 3 or more fixes and the bug persists
- Each “fix” introduces a new bug
- The code has changed so much you cannot tell what the original intent was
- The AI is going in circles, trying the same approaches
How to re-prompt after reverting:
I reverted to the previous working version.
The original problem was: [describe the bug]
We tried these approaches and they did not work:
1. [approach 1] — failed because [reason]
2. [approach 2] — failed because [reason]
Please suggest a completely different approach.
Do not try the same solutions again.
The key is telling the AI what was already tried. Without this, it will suggest the same fixes.
Using AI to Analyze Logs
AI is surprisingly good at finding patterns in log files.
Prompt:
Here are the last 50 lines of our application logs
from when the crash happened:
[paste logs]
Find any anomalies. Look for:
- Errors or warnings before the crash
- Unusual timing patterns
- Missing log entries (gaps in the sequence)
- Database connection issues
- Memory or resource warnings
For large log files, do not paste everything. Extract the relevant time window and give AI the context of what happened.
Prompt for pattern analysis:
These are all the 500 errors from the last 24 hours.
Group them by root cause.
Which endpoint has the most failures?
Is there a time pattern?
[paste error summary]
Plan Mode for Safe Debugging
Claude Code has a Plan Mode that analyzes code without making changes. This is essential for debugging production issues where you need to understand the problem before touching anything.
Use plan mode. Do not edit any files.
We have a memory leak in the notification service.
Memory usage grows by 50MB per hour.
Analyze the code in src/services/notificationService.ts.
Look for:
- Event listeners that are never removed
- Caches that grow without bounds
- Closures that hold references to large objects
- Intervals or timeouts that are never cleared
Give me your analysis. I will decide what to fix.
Plan mode lets AI trace through the code, form hypotheses, and present findings without risking accidental changes to working code.
Debugging Across Multiple Files
Some bugs only appear when you look at multiple files together. AI is better at this than humans because it can hold more context.
Prompt:
I have a bug where order totals are calculated wrong.
The total should include tax but it does not.
These files are involved:
- src/services/orderService.ts (calculates the order)
- src/services/taxService.ts (calculates tax)
- src/controllers/orderController.ts (handles the API request)
- src/types/order.ts (type definitions)
Trace the flow from when the API request comes in
to when the total is returned. Find where the tax
calculation gets lost.
Claude Code can read all four files and trace the data flow. A common finding: the tax is calculated but not added to the total because the order type does not include a tax field, or the controller calls calculateTotal() before calculateTax().
A Systematic Review Checklist
After AI generates or modifies code, check these 10 things:
- Does it compile? Run the build. TypeScript, Kotlin, and Rust compilers catch many AI mistakes.
- Do the tests pass? Run the full test suite, not just the affected tests.
- Are there null checks? Every database lookup, API call, and optional field access needs a null check.
- Are error messages helpful? “Something went wrong” is not a useful error message.
- Are there race conditions? If the code runs concurrently, check for shared state issues.
- Did AI add new dependencies? Check that they exist and are the right packages.
- Are the API calls correct? Verify function signatures against documentation.
- Does it handle the empty case? Empty arrays, empty strings, zero values.
- Is the error handling specific? Catching all exceptions hides bugs.
- Does git blame make sense? Can you trace which changes are AI-generated?
Key Takeaways
- Give AI visibility. Full stack traces, complete error messages, and relevant logs. The more context, the better the fix.
- Watch for AI-specific bugs. Race conditions, null handling, API hallucinations, and stale patterns are the most common AI code bugs.
- Use the rubber duck technique. Explain what you think happens and let AI find where your understanding is wrong.
- Know when to revert. Three failed fixes means it is time to start fresh with a different approach.
- Use Plan Mode for production issues. Analyze first, fix second.
What’s Next?
In Multi-Agent Workflows — AI Teams That Code Together, you will learn how to use multiple AI agents working in parallel. Debugging gets even more interesting when multiple agents are writing code at the same time.
Part 13 of the Vibe Coding series.