Skip to main content

Debugging with Claude Code: Advanced Techniques

Move beyond basic error messages. Learn how to leverage the debugger agent, test-runner, and parallel investigation for systematic root cause analysis.

Debugging is where Claude Code truly shines. Instead of manually tracing through code, you can leverage Claude’s ability to understand context, analyze patterns, and reason about behavior—with specialized agents designed specifically for debugging.

This guide covers debugging subagents, the Agent tool for parallel investigation, and advanced techniques that go beyond “fix this error.”

Updated October 21, 2026: Switched the examples to the Agent tool and current models, noted that debugger and test-runner are custom subagents you define (the built-ins are Explore, Plan, and general-purpose), corrected Explore’s model and the task-list tools’ availability, and added the /debug command.

Official Debugging Tools

The debugger Agent

Claude Code’s built-in subagents are Explore, Plan, and general-purpose; debugger is a custom subagent you define in .claude/agents/debugger.md for systematic root cause analysis. For a built-in starting point, run /debug, the bundled skill that turns on debug logging for the session and investigates from the log.

---
name: debugger
description: Investigates errors and test failures to find the root cause. Use for stack traces and unexpected behavior.
tools: Read, Glob, Grep, Bash
model: sonnet
---

You are a debugger. Reproduce the problem, trace it to its root cause,
and propose the smallest fix that addresses the cause rather than the symptom.

Claude then delegates to it through the Agent tool (named Task before v2.1.63; Task(...) still works as an alias):

Agent({
  subagent_type: "debugger",
  model: "sonnet",
  prompt: `
    Investigate: TypeError: Cannot read property 'id' of undefined
    at CheckoutForm.handleSubmit (checkout.tsx:45)

    Context: Error occurs when submitting checkout with empty cart.
    Find root cause and suggest fix.
  `
})

When to use debugger agent:

  • Error investigation requiring deep analysis
  • Root cause analysis for complex bugs
  • Systematic tracing through multiple files
  • Understanding unexpected behavior

The test-runner Agent

The test-runner agent is another custom subagent; it validates fixes and ensures no regressions:

Agent({
  subagent_type: "test-runner",
  model: "haiku",
  prompt: `
    Run tests related to checkout functionality.
    Analyze any failures and report coverage gaps.
  `
})

When to use test-runner agent:

  • After implementing fixes
  • To verify reproduction tests pass
  • To check for regression coverage
  • To analyze test coverage gaps

The Explore Agent for Bug Hunting

Explore is a built-in, read-only agent that excels at rapid codebase investigation: Write and Edit are denied to it. By default it runs on your main conversation’s model (when that is Fable, it runs on the model the opus alias resolves to). A model passed with the call takes precedence, so the examples below keep exploration on Haiku; defining your own Explore agent in .claude/agents/ overrides the built-in for every call.

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: `
    Explore authentication module (thoroughness: medium).
    Find all places where user session might be null.
  `
})

Thoroughness levels: Claude passes quick for targeted lookups, medium for balanced exploration, or very thorough for comprehensive analysis.

LevelUse Case
quickFind a specific error pattern
mediumMap related code paths
very thoroughComplete flow analysis

The Debugging Mindset Shift

Traditional Debugging

1. See error
2. Google error message
3. Try random Stack Overflow solutions
4. Add console.log statements
5. Repeat until fixed

Claude Code Debugging

1. See error
2. Launch parallel investigation agents
3. Let agents trace the root cause
4. Understand why it happened
5. Fix properly with test-runner verification

The difference: Claude doesn’t just fix the symptom—it understands the disease.

Technique 1: Context-Rich Error Reporting

Don’t just paste the error. Give Claude the full story.

Bad Approach

"Fix this error: TypeError: Cannot read property 'id' of undefined"

Good Approach

"I'm getting this error when submitting the checkout form:

Error: TypeError: Cannot read property 'id' of undefined
  at CheckoutForm.handleSubmit (checkout.tsx:45)
  at processOrder (orders.ts:123)
  at <anonymous>

What I was doing:
- Logged in as test user
- Added 2 items to cart
- Clicked submit on checkout

What I expected:
- Order to be created
- Redirect to confirmation page

The error started after I merged PR #234 yesterday.
Relevant recent changes: Updated cart state management."

Why This Works

Claude can now:

  • Trace the stack to find the origin
  • Consider recent changes as suspects
  • Understand the expected behavior
  • Reproduce the scenario mentally

Technique 2: Parallel Investigation with the Agent Tool

From the official subagents documentation, use multi-agent analysis for complex bugs. Send the calls in one message so they run concurrently:

// Launch 5 parallel investigation agents
Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Search for session/cookie handling changes this week (thoroughness: quick)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Analyze authentication middleware patterns (thoroughness: medium)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Check for race conditions in auth state (thoroughness: quick)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Review error logs for auth-related errors (thoroughness: quick)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Find timeout/expiry configuration changes (thoroughness: quick)"
})

Time comparison:

  • Sequential investigation: 5 × 30s = 150 seconds
  • Parallel investigation: max(30s) = 30 seconds
  • Best-case example: about one fifth of the serial wall-clock time, before startup and coordination overhead

Each agent focuses on one hypothesis. The first to find strong evidence guides the investigation.

Technique 3: The Debugger-Test Runner Workflow

Combine debugger and test-runner agents for comprehensive debugging:

Phase 1 - Investigation (debugger agent):
→ Analyze error and stack trace
→ Identify root cause
→ Propose fix

Phase 2 - Verification (test-runner agent):
→ Run existing tests
→ Verify fix doesn't break other functionality
→ Suggest additional test coverage

Phase 3 - Regression Prevention:
→ Create reproduction test
→ Ensure test fails without fix
→ Ensure test passes with fix

Implementation:

// Phase 1: debugger investigates
Agent({
  subagent_type: "debugger",
  model: "sonnet",
  prompt: `
    Investigate checkout failure.
    Error: TypeError at checkout.tsx:45
    Find root cause and propose fix.
  `
})

// Phase 2: test-runner verifies (after fix)
Agent({
  subagent_type: "test-runner",
  model: "haiku",
  prompt: `
    Run all checkout-related tests.
    Report any failures and coverage analysis.
  `
})

Technique 4: Behavioral Analysis

When you know something is wrong but can’t pinpoint it.

"Something's wrong with the search feature. Results seem off.

Behavior I'm seeing:
- Search for 'javascript' returns Python articles
- Exact title matches don't appear first
- Results change on page refresh (shouldn't happen)

Help me understand:
1. What search algorithm are we using?
2. Where is the ranking logic?
3. What could cause non-deterministic results?
4. How can we add debugging to trace a query?"

Claude will:

  • Map the search pipeline
  • Identify potential issues at each stage
  • Suggest instrumentation points
  • Help create a debugging plan

Technique 5: Regression Hunting with Git Integration

When something that worked suddenly doesn’t:

"The export feature broke. It was working on Friday.

git log shows these changes since Friday:
- abc123: Updated PDF library
- def456: Refactored file service
- ghi789: Added new export format

Help me:
1. Identify which commit most likely caused the regression
2. Explain what each change does
3. Suggest how to verify the culprit
4. Provide a fix if you can identify the issue"

Parallel analysis approach:

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Analyze commit abc123 impact on export feature (thoroughness: quick)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Analyze commit def456 impact on export feature (thoroughness: quick)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Analyze commit ghi789 impact on export feature (thoroughness: quick)"
})

Technique 6: Error Pattern Analysis

For recurring or related errors:

"We're seeing multiple related errors in production:

1. TypeError: Cannot read 'user' of null (dashboard.tsx)
2. TypeError: Cannot read 'profile' of null (settings.tsx)
3. TypeError: Cannot read 'preferences' of null (notifications.tsx)

All involve user data. What's the common cause?
Why might user be null in these places?"

Claude will:

  • Identify the shared pattern (user data access)
  • Trace the user data flow
  • Find where the null originates
  • Suggest a systematic fix

Technique 7: Performance Debugging

When things are slow, use parallel profiling:

// Launch parallel performance investigation
Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Find N+1 query patterns in dashboard data fetching (thoroughness: medium)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Identify waterfall request patterns in API calls (thoroughness: medium)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Find unnecessary re-renders in React components (thoroughness: quick)"
})

Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: "Check for missing database indexes on slow queries (thoroughness: quick)"
})

Technique 8: State Debugging

For complex state management issues:

"The shopping cart state is getting corrupted.

Symptoms:
- Items appear/disappear randomly
- Quantities reset to 1
- Total doesn't match items

We use Redux Toolkit. Cart slice is in store/cart.ts.

I suspect a race condition but can't reproduce it consistently.
Help me trace where state mutations might be happening incorrectly."

Claude will:

  • Analyze the cart reducer
  • Find potential mutation issues
  • Identify race conditions in async actions
  • Suggest state debugging tools

Debugging Workflow with Subagents

Step 1: Gather Context and Launch Investigation

// Launch parallel investigation
Agent({
  subagent_type: "Explore",
  model: "haiku",
  prompt: `
    Explore error context (thoroughness: medium).
    Find all files related to: [error location]
    Map data flow and dependencies.
  `
})

Step 2: Deep Analysis with debugger Agent

Agent({
  subagent_type: "debugger",
  model: "sonnet",
  prompt: `
    Context from exploration: [results]
    Error: [full stack trace]

    Perform root cause analysis:
    1. Trace execution path
    2. Identify failure point
    3. Determine fix
  `
})

Step 3: Verify with test-runner Agent

Agent({
  subagent_type: "test-runner",
  model: "haiku",
  prompt: `
    After fix applied to [files]:
    1. Run related tests
    2. Check for regressions
    3. Report coverage
  `
})

Step 4: Prevent Regression

After identifying the cause:
- Understand WHY it happened
- Fix the root cause, not just the symptom
- Add a test to prevent regression
- Check for similar issues elsewhere

Common Debugging Patterns

The Null Reference Pattern

Error: Cannot read property 'X' of undefined

Questions to ask:
- Where should X come from?
- What conditions make it undefined?
- Is there a race condition?
- Is there a missing initialization?

The Async Timing Pattern

Symptoms: Intermittent failures, works sometimes

Questions to ask:
- Are there race conditions?
- Are promises handled correctly?
- Is there missing await?
- Are there timing assumptions?

The State Mutation Pattern

Symptoms: UI doesn't update, stale data

Questions to ask:
- Is state being mutated directly?
- Are immutability rules followed?
- Are dependencies in useEffect correct?
- Is memoization working correctly?

The Integration Pattern

Symptoms: Works locally, fails in production

Questions to ask:
- Are environment variables correct?
- Are URLs/endpoints correct?
- Are there network/CORS issues?
- Are there timeout differences?

Model Selection for Debugging

From the Claude Code model configuration docs:

TaskRecommended ModelWhy
Quick file searchHaiku 5.5Fast, cheap
Pattern matchingHaiku 5.5Fast, cheap
Root cause analysisSonnet 5.5Balanced reasoning
Complex debuggingOpus 5.5The default model; raise effort with /effort high
Critical bug fixFable 5.1Highest intelligence, best for long investigations

Opus 5.5, Sonnet 5.5, and Haiku 5.5 run at medium effort by default, so a stubborn bug is often a case for /effort high or xhigh rather than a different model. max is the deepest level and applies to the current session only.

Quick model switching (v2.0.65+): Press Option+P (macOS) or Alt+P (Windows/Linux) during prompting.

Real-World Example: Bug Investigation

User: "Production error: 'Payment failed' but money was charged."

Parallel investigation (5 Explore agents):
→ Search payment logs for error pattern
→ Analyze payment service error handling
→ Check Stripe webhook handlers
→ Review recent payment changes
→ Find similar issues in error tracking

Results:
- Agent 3 finds: Webhook handler doesn't retry on timeout
- Agent 4 confirms: Recent change added new timeout logic
- Agent 1 shows: Pattern started after deploy on Jan 5

Root cause identified in ~1 minute vs 10+ sequential.

Getting Started

Today:

  1. Run /debug on your next bug, then write a debugger subagent for the follow-up
  2. Use parallel Explore agents for investigation
  3. Verify fixes with test-runner agent

This week:

  1. Develop a debugging prompt template
  2. Use parallel investigation for complex bugs
  3. Create reproduction tests for every fix

This month:

  1. Build debugging patterns for your common issues
  2. Integrate debugger + test-runner workflow
  3. Share patterns with your team

The goal isn’t just to fix bugs faster—it’s to understand your codebase better through each debugging session.


Sources: Claude Code Documentation, Subagents, Commands, Model configuration, Claude Code GitHub