Debugging with AI
AI doesn't just fix bugs — it explains root causes, reads stack traces in seconds, and spots issues you'd miss at 11pm.
The AI Debugging Mindset
Most developers use AI debugging wrong: they paste an error and say "fix this." That gets you a patch, not an understanding. The right approach is to use AI to understand first, fix second.
The three debugging modes:
- "Explain this error" — understand what went wrong and why, before touching code
- "Find the bug" — give AI the code + symptoms, ask it to identify the root cause
- "Fix and explain" — ask for the fix AND an explanation of what was wrong
Stack Trace Reading
// Paste the full stack trace — not just the last line // Bad: "I get a TypeError, help" // Good: paste everything below Prompt template: "I'm getting this error in my [Node/Python/Go] app. Here's the full stack trace: [paste full stack trace] Here's the code at the relevant line: [paste the function or file] Explain: 1. What is the root cause? 2. Why does this happen? 3. What's the fix? 4. How do I prevent this class of error in future?" // Example output from Claude: // Root cause: You're calling .json() on a Response object // that has already been consumed. Response bodies can only // be read once. You called res.text() earlier in the middleware // which drained the stream. // Fix: Clone the response before reading: res.clone().json() // Prevention: Use a single body-reading method per response, // or clone immediately after fetch if you need to read twice.
The /fix Command (Copilot)
// Select the broken code → /fix in Copilot Chat
// Copilot reads the selection + error context and suggests a fix
// For better /fix results, first write a comment:
// BUG: This throws "Cannot read properties of undefined"
// when user.profile is null
function getDisplayName(user: User): string {
return user.profile.firstName + ' ' + user.profile.lastName
}
// Now /fix knows exactly what the bug is
// Copilot suggests:
function getDisplayName(user: User): string {
if (!user.profile) return user.email ?? 'Unknown User'
return [user.profile.firstName, user.profile.lastName]
.filter(Boolean)
.join(' ') || user.email ?? 'Unknown User'
}Root Cause Analysis for Hard Bugs
// For intermittent or complex bugs, give more context: "This function works correctly in unit tests but fails in production about 1 in 50 requests. Here's the function: [code] It's a race condition I think, but I can't reproduce it locally. The error is: [error message] The function runs in a serverless environment with concurrent execution. What are the possible race conditions here? What would you add to diagnose which one is occurring?" // Claude identifies: // 1. Shared mutable state in module scope (the cache object) // not protected for concurrent access // 2. Time-of-check/time-of-use: checking cache.has(key) then // reading cache.get(key) are two separate operations // Suggests: add a mutex or use an atomic read-then-set pattern
Debugging Patterns by Error Type
Paste these prompt templates for common error types:
- TypeError/null: "Why would [variable] be undefined/null here? Walk through every code path that leads to this line."
- Async bugs: "Is there a timing issue in this async code? What happens if the promise rejects here?"
- Performance: "This query takes 8s. Explain what it's doing and why it might be slow. What indexes would help?"
- Logic bugs: "This function returns [wrong value] when I pass [input]. Walk through what it actually does step by step."
- Build errors: "Here's my TypeScript error: [paste]. Explain in plain English what type mismatch is happening."
Claude Code for Debugging Sessions
# Claude Code can read logs, check related files, trace the call chain > I'm getting this error: [paste error] The relevant file is src/services/payment.ts Can you trace through the call chain to find the root cause? # Ask for a reproduction case > Write a minimal test that reproduces this bug so I can debug it without running the full app # Compare expected vs actual behaviour > This function should sort users by last login descending. Walk through what it actually does and explain the bug. # Ask for defensive improvements > Fix the immediate bug, then suggest what defensive coding would prevent this entire class of null-pointer errors in this service
Lesson 42 Quick Reference
Explain first
Ask "what is the root cause?" before asking for the fix — builds real understanding
Full stack trace
Always paste the complete trace, not just the error message
/fix (Copilot)
Select broken code + /fix — add a comment describing the bug for better results
Race condition prompt
"What are the possible race conditions here?" — works well for async/concurrent bugs
Logic trace
"Walk through what this function actually does step by step" for logic bugs
Minimal repro
Ask Claude: "Write a minimal test that reproduces this bug"