Debugging and Fixing Errors
Debugging is one of the most time-consuming parts of software development. You stare at error messages, trace through stack traces, add console.log statements, and search Stack Overflow. Claude Code transforms this process by reading your errors, understanding your code, and applying targeted fixes.
In this lesson, you will learn how to share errors with Claude Code effectively, debug different types of issues, and develop an efficient fix-test-iterate loop.
Sharing Error Messages
The simplest debugging workflow with Claude Code is pasting an error message directly into the conversation. Claude Code does not just read the error -- it reads the files mentioned in the error to understand the full context.
> I'm getting this error when I start the dev server:
Error: Module not found: Can't resolve '@/lib/database'
Import trace for requested module:
./src/app/api/users/route.ts
at Object.resolve (webpack/lib/Resolver.js:326:11)
Claude Code will:
- Read
src/app/api/users/route.tsto see the import statement - Check what files exist in
src/lib/to see if the module exists under a different name - Check
tsconfig.jsonto verify the path alias configuration - Propose and apply the fix
Claude Code: The issue is that the file was renamed from `database.ts` to `db.ts`
but the import in route.ts wasn't updated. I'll fix the import.
[Edits src/app/api/users/route.ts]
Changed: import { db } from '@/lib/database'
To: import { db } from '@/lib/db'
Tips for Sharing Errors
Copy the complete error message, not just a summary. Include:
- The error type and message
- The file path and line number if shown
- The full stack trace
- Any relevant context about when the error occurs
# Good - complete error with context
> I get this error when clicking the submit button on the login form:
TypeError: Cannot read properties of undefined (reading 'email')
at LoginForm (src/components/LoginForm.tsx:24:18)
at renderWithHooks (react-dom.js:1234:22)
# Less helpful - too vague
> The login form is broken
Stack Trace Analysis
Stack traces tell you where an error occurred and the chain of function calls that led to it. Claude Code excels at reading stack traces because it can open every file mentioned and understand the full picture.
> I'm seeing this error in production:
Unhandled Runtime Error
TypeError: Cannot destructure property 'user' of 'context' as it is null.
Source
src/components/UserProfile.tsx (18:9) @ UserProfile
Call Stack:
UserProfile src/components/UserProfile.tsx (18:9)
ProfilePage src/app/profile/page.tsx (12:5)
renderWithHooks node_modules/react-dom/...
Claude Code reads both files in the stack trace:
Claude Code: The issue is that UserProfile.tsx is trying to destructure
the auth context, but it's being rendered outside of the AuthProvider.
[Reads src/components/UserProfile.tsx]
[Reads src/app/profile/page.tsx]
[Reads src/app/layout.tsx]
The problem is in layout.tsx - the AuthProvider wraps most of the app,
but the profile page is outside its scope due to the route group structure.
Here are two ways to fix this:
1. Move AuthProvider higher in the component tree
2. Add a null check in UserProfile.tsx
I'll implement option 2 since it's safer and handles edge cases:
[Edits src/components/UserProfile.tsx]
Added a null check: if (!context) return <LoginPrompt />
Fixing Failing Tests
One of the most efficient debugging workflows is telling Claude Code to run your tests and fix whatever fails.
The Basic Workflow
> Run the tests and fix any failures
Claude Code will:
- Run your test suite (detecting whether you use Jest, Vitest, Pytest, etc.)
- Read the test output to identify failures
- Read both the test files and the source files
- Determine whether the bug is in the test or the implementation
- Apply the fix
Claude Code: I'll run the test suite.
[Runs: npm test]
3 tests failed:
FAIL src/__tests__/utils/formatPrice.test.ts
- formats zero correctly (Expected "$0.00", received "$NaN")
- handles negative prices (Expected "-$5.99", received "$-5.99")
FAIL src/__tests__/api/orders.test.ts
- creates order with valid data (timeout exceeded)
Let me fix these one at a time.
[Reads src/utils/formatPrice.ts]
[Reads src/__tests__/utils/formatPrice.test.ts]
The formatPrice function doesn't handle zero or negative numbers correctly.
[Edits src/utils/formatPrice.ts]
Added: if (price === 0) return '$0.00'
Fixed: negative sign now placed before the dollar sign
[Reads src/app/api/orders/route.ts]
[Reads src/__tests__/api/orders.test.ts]
The orders test is timing out because the mock database isn't being
set up correctly. The test is using an outdated mock.
[Edits src/__tests__/api/orders.test.ts]
Updated the database mock to match the current schema
[Runs: npm test]
All tests passing.
Targeting Specific Tests
You can also point Claude Code at specific test failures:
> The test in src/__tests__/auth.test.ts called "redirects
unauthenticated users" is failing. Can you fix it?
> Run just the payment tests and fix any issues:
npm test -- payments.test.ts
TypeScript Errors
TypeScript errors are a particularly good match for Claude Code because they often involve understanding type relationships across multiple files.
> I'm getting a TypeScript error:
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
src/components/UserProfile.tsx:31:5
Claude Code reads the component and the types to understand the issue:
Claude Code: [Reads src/components/UserProfile.tsx]
[Reads src/types/user.ts]
The User type has `bio` as an optional field (bio?: string), but you're
passing it to a component that expects a required string prop. I'll fix
this with a default value.
[Edits src/components/UserProfile.tsx]
Changed: <BioSection text={user.bio} />
To: <BioSection text={user.bio ?? ''} />
Complex Type Errors
TypeScript errors can get cryptic, especially with generics. Claude Code can decode them:
> I don't understand this TypeScript error, can you fix it?
Type 'InferGetServerSidePropsType<typeof getServerSideProps>' is not
assignable to type '{ posts: Post[]; totalPages: number; }'.
Types of property 'posts' are incompatible.
Type 'SerializedPost[]' is not assignable to type 'Post[]'.
Property 'createdAt' is missing in type 'SerializedPost'.
Claude Code will trace through the type chain and fix the mismatch, often explaining the root cause so you understand why it happened.
Runtime Bugs
Not all bugs produce error messages. Sometimes the code runs but does not do what you expect. For these situations, describe the unexpected behavior:
> The shopping cart total shows the wrong amount. When I add a $10 item
and a $20 item, it shows $10 instead of $30. The cart page is at
src/app/cart/page.tsx.
Claude Code will read the cart logic and trace the calculation:
Claude Code: [Reads src/app/cart/page.tsx]
[Reads src/lib/cart.ts]
Found the issue. In calculateTotal(), the reduce function is using
assignment (=) instead of addition (+=), so it only keeps the last
item's price instead of summing them all.
[Edits src/lib/cart.ts]
Changed: total = item.price * item.quantity
To: total += item.price * item.quantity
Describing Runtime Bugs Effectively
Be as specific as you can about:
- What you expected to happen
- What actually happened
- Steps to reproduce the issue
- Which part of the app is affected
# Helpful description
> When I click "Save" on the settings page, the form appears to submit
(the button shows a spinner) but the changes aren't persisted. When
I refresh the page, the old values are back. The settings page is at
src/app/settings/page.tsx.
# Less helpful
> Settings don't save
The Debug Loop
Complex bugs often require multiple rounds of investigation. The debug loop with Claude Code looks like this:
Round 1: Initial Diagnosis
> The user registration is failing silently. No error in the console,
but the user doesn't get created in the database.
Claude Code investigates, reads the relevant files, and proposes a fix.
Round 2: Testing and Reporting Back
> I tried your fix but it's still not working. Now I'm seeing this
in the network tab: the POST to /api/auth/register returns a 500
but with no error body.
Claude Code digs deeper, now focusing on the server-side error handling.
Round 3: Narrowing Down
> Okay, the registration works now but only for email/password.
When I try to register with Google OAuth, it still fails with
"invalid_grant" in the server logs.
Each round narrows the problem. Claude Code retains all the context from previous rounds, so it understands the full history of what has been tried.
Using Console Output and Logs
You can share console output and log messages to help Claude Code diagnose issues:
> I added some console.logs and here's what I see:
[API] Received request: POST /api/orders
[API] User ID: usr_abc123
[API] Cart items: 3
[API] Calculating total...
[API] Total: NaN
[API] Error: Invalid order total
The console logs are in src/app/api/orders/route.ts
Claude Code can read the file, see where the NaN comes from, and fix the calculation.
Having Claude Code Add Logs
You can also ask Claude Code to add logging to help diagnose an issue:
> The webhook endpoint is failing intermittently. Can you add detailed
logging to src/app/api/webhooks/stripe/route.ts so we can see what's
happening when it fails?
After collecting the logs:
> Here's the log output from a failed webhook:
[Webhook] Received event: invoice.payment_succeeded
[Webhook] Customer: cus_xyz789
[Webhook] Looking up user...
[Webhook] User found: null
[Webhook] ERROR: Cannot update subscription for null user
Now Claude Code has the context to fix the root cause.
Real Example: Fixing a React Hydration Error
Hydration errors are among the most confusing bugs in React. Let us walk through how Claude Code handles one.
> I'm getting this warning in the console and the page flickers
on load:
Warning: Text content did not match.
Server: "March 6, 2026" Client: "3/6/2026"
It's happening on the blog post page.
Claude Code investigates:
Claude Code: [Reads src/components/blog/PostDate.tsx]
The issue is a hydration mismatch caused by date formatting. The component
uses toLocaleDateString() which produces different output on the server
(Node.js) vs the client (browser) because they may have different locale
settings.
The server renders "March 6, 2026" (en-US long format) while the client
renders "3/6/2026" (short format).
Here's the fix - I'll use an explicit locale and format options to ensure
consistent output:
[Edits src/components/blog/PostDate.tsx]
Changed:
{new Date(post.date).toLocaleDateString()}
To:
{new Date(post.date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})}
This ensures both server and client produce the same formatted date
string, eliminating the hydration mismatch.
This is a great example of a bug where understanding the cause (server/client environment differences) is just as important as the fix itself. Claude Code explains both.
Debugging Strategies Summary
Here is a quick reference for different types of bugs and how to approach them with Claude Code:
| Bug Type | What to Share | Example Prompt |
|---|---|---|
| Build error | Full error output | "I get this error when running npm run build: ..." |
| Runtime error | Error message + stack trace | "This TypeError appears when I click submit: ..." |
| Type error | TypeScript error with file/line | "Fix the TypeScript error in UserProfile.tsx line 31" |
| Test failure | Test output | "Run the tests and fix the failures" |
| Silent failure | Expected vs actual behavior | "The form submits but data isn't saved to the database" |
| Performance | Description of slowness | "The products page takes 8 seconds to load" |
| Intermittent | When it happens/doesn't | "The API returns 500 about 1 in 10 requests" |
What You Learned
In this lesson, you learned how to use Claude Code for debugging:
- Paste complete error messages with stack traces for the best results
- Claude Code reads the files mentioned in errors to understand full context
- Tell Claude Code to run tests and fix failures automatically
- For TypeScript errors, Claude Code traces through type relationships across files
- Describe runtime bugs with expected vs actual behavior
- Use the debug loop: diagnose, test, report back, iterate
- Share console output and logs to give Claude Code more diagnostic information
- Claude Code explains the root cause, not just the fix, helping you learn
In the next lesson, you will learn how to use Claude Code to refactor existing code safely and efficiently.
Questionário
Discussion
Sign in to join the discussion.

