Skip to main content
Agent Type: Systematic DebuggingTools: Read, Glob, Grep, BashModel: opus (advanced reasoning)Memory: project (recalls previous bugs)

Overview

The Debugger agent performs methodical bug investigation that narrows down root causes before proposing fixes. It uses hypothesis-driven debugging, examines git history, searches for similar patterns, and proposes minimal fixes with clear rationale.

When to Use

Use the Debugger agent when facing:

Hard Bugs

Bugs that aren’t immediately obvious or have unclear causes

Test Failures

Failing tests that need systematic investigation

Runtime Errors

Production errors or crashes requiring root cause analysis

Regressions

Features that worked before but are now broken

Configuration

---
name: debugger
description: Specialized debugging agent. Use when facing hard bugs, test failures, or runtime errors that need systematic investigation.
tools: ["Read", "Glob", "Grep", "Bash"]
model: opus
memory: project
---

Configuration Details

model
string
default:"opus"
Uses Claude Opus for advanced reasoning in complex debugging scenarios
memory
string
default:"project"
Recalls previous bugs in the same area to identify patterns

Five-Step Workflow

The Debugger follows a systematic 5-step process:

Step 1: Reproduce

Objective: Confirm the bug and capture exact error details
1

Run the Failing Test

Execute the test or reproduce the error condition
2

Capture Error Details

Save exact error message, stack trace, and context
3

Classify Bug Type

Determine if this is a regression (worked before) or new behavior
$ npm test -- user.test.ts

FAIL tests/user.test.ts
 should update user profile (52ms)

Error: Expected status 200, received 500
    at Object.<anonymous> (tests/user.test.ts:45:7)

Stack trace:
  at updateProfile (src/api/user.ts:89)
  at handler (server/routes/user.ts:34)

Type: Regression (test passed 3 days ago)

Step 2: Hypothesize

Objective: Generate 2-3 ranked hypotheses about the cause
Each hypothesis includes:
  • Likelihood (percentage)
  • Evidence for (what supports this)
  • Evidence against (what contradicts this)
  • Test (how to verify)
Hypothesis 1 (70%): [Most likely cause]
  Evidence for:
    - [Supporting fact 1]
    - [Supporting fact 2]
  Evidence against:
    - [Contradicting fact]
  Test:
    - [How to verify this hypothesis]

Hypothesis 2 (20%): [Alternative cause]
  Evidence for:
    - [Supporting fact]
  Evidence against:
    - [Contradicting fact]
  Test:
    - [How to verify]

Hypothesis 3 (10%): [Unlikely but possible]
  Evidence for:
    - [Supporting fact]
  Evidence against:
    - [Contradicting fact]
  Test:
    - [How to verify]

Step 3: Investigate

Objective: Test each hypothesis starting with the most likely
Examine the code involved in each hypothesis
  • Follow the stack trace
  • Read functions that could cause the issue
  • Check error handling and edge cases
Review recent changes to affected files
git log --oneline --since="1 week ago" -- src/api/user.ts
git blame src/api/user.ts
git show <commit-hash>
Recent changes are more likely to be the cause.
Find similar code that works correctly
  • How do other APIs handle null users?
  • Are there similar patterns that don’t fail?
  • What’s different about the failing case?
Add targeted logging if needed
console.log('User data:', user);
console.log('User ID:', userId);
But only as a last resort—prefer reading code first.
Testing Hypothesis 1: Profile API returns null for deleted users

1. Checking database:
   $ psql -c "SELECT * FROM users WHERE id = 12345"
   (0 rows)
   
 User 12345 does not exist!

2. Reading getUserData code:
   src/services/user.ts:142
   
   const user = await db.findUser(userId);
   return user.id; // Error here if user is null
   
 No null check before accessing user.id

3. Checking git history:
   $ git log --oneline --since="1 week ago" -- src/services/user.ts
   
   abc1234 Add user deletion feature
   
 User deletion added 3 days ago, matches timeline

4. Checking similar code:
   src/services/admin.ts has:
   
   const user = await db.findUser(userId);
   if (!user) return null;
   return user.id;
   
 Other code properly checks for null

CONCLUSION: Hypothesis 1 confirmed!
Root cause: getUserData doesn't handle null user

Step 4: Root Cause

Objective: Present the confirmed root cause with details
ROOT CAUSE: [What's actually wrong]
WHERE: [file:line]
WHY: [How it got this way]
SINCE: [When it was introduced, if knowable]
ROOT CAUSE: getUserData doesn't handle deleted users
WHERE: src/services/user.ts:142
WHY: User deletion feature was added without updating dependent code
SINCE: Commit abc1234 (3 days ago, March 5th)

Details:
When a user is deleted, db.findUser(userId) returns null.
getUserData tries to access user.id without checking if user exists.
This throws "Cannot read property 'id' of undefined".

Other parts of the codebase (admin.ts) properly check for null,
but this code path was missed during the deletion feature implementation.

Step 5: Fix Proposal

Objective: Propose the minimal fix with clear rationale
FIX: [Description of the fix]
CHANGES:
  - file.ts:42 - [What to change]
  - file.test.ts:10 - [Test changes]
RISK: [low/medium/high]
TESTS: [How to verify the fix]
FIX: Add null check before accessing user properties

CHANGES:
  - src/services/user.ts:142 - Add null check
    Before:
      const user = await db.findUser(userId);
      return user.id;
    
    After:
      const user = await db.findUser(userId);
      if (!user) return null;
      return user.id;
  
  - tests/services/user.test.ts:89 - Add deleted user test
    Test that getUserData returns null for deleted users

RISK: Low
- Minimal change, follows existing patterns
- Other code already returns null for missing users
- Backward compatible (null is expected return type)

TESTS:
1. Existing tests should still pass
2. New test: getUserData with deleted user ID returns null
3. Manual: Profile page shows "User not found" instead of crashing
Debugger waits for approval before implementing the fix.

Rules and Constraints

The Debugger investigates systematically. No random fixes or “shotgun debugging.”
Never apply fixes without confirming the root cause. Fixing symptoms doesn’t solve the problem.
Recent changes are more likely to be the cause. Always check git history.
Recall previous bugs in the same area to identify patterns.
After 3 investigation rounds without finding root cause, escalate to user with findings.
Document debugging insights using [LEARN] Debugging: <insight> syntax.

Anti-Patterns to Avoid

The Debugger actively avoids these common mistakes:

Shotgun Debugging

Don’t: Change random things hoping something worksDo: Form hypothesis, test systematically

Ignoring Stack Traces

Don’t: Skip over stack traces—they’re noiseDo: Stack traces tell you exactly where to look

Not Reproducing First

Don’t: Start fixing before confirming the bugDo: Always reproduce first—you can’t fix what you can’t see

Fixing Symptoms

Don’t: Apply quick fixes to symptomsDo: Find and fix the root cause

Example Debugging Session

User: The user profile page is crashing in production

=== STEP 1: REPRODUCE ===

Reproducing error...
Checking production logs...

Error found:
TypeError: Cannot read property 'id' of undefined
    at getUserData (src/services/user.ts:142:15)
    at renderProfile (src/pages/Profile.tsx:28:9)

User ID: 12345
Timestamp: 2026-03-08 14:32:01

Running test locally...
Test passes with existing user.
Test fails with user ID that doesn't exist.

Classification: Regression
- Feature worked before
- Started 3 days ago after user deletion feature deployed

=== STEP 2: HYPOTHESIZE ===

Hypothesis 1 (70%): getUserData doesn't handle deleted users
  Evidence for:
    - Error message indicates undefined user object
    - User deletion feature added recently
    - Error only happens for specific user IDs
  Evidence against:
    - Should have been caught in testing
  Test:
    - Check if user 12345 exists in database
    - Read getUserData implementation

Hypothesis 2 (20%): Cache returning stale data
  Evidence for:
    - Using Redis for user data
    - Deletion might not invalidate cache
  Evidence against:
    - Cache has 5min TTL, user deleted 2 days ago
  Test:
    - Check cache invalidation on user deletion

Hypothesis 3 (10%): Database replication lag
  Evidence for:
    - Using read replicas
  Evidence against:
    - Lag is typically < 1s, user deleted days ago
  Test:
    - Query primary database directly

=== STEP 3: INVESTIGATE ===

Testing Hypothesis 1...

Checking database:
$ psql production -c "SELECT * FROM users WHERE id = 12345"
(0 rows)

✓ User 12345 does not exist

Reading getUserData code:
src/services/user.ts:142

export async function getUserData(userId: number) {
  const user = await db.findUser(userId);
  return user.id; // ← No null check!
}

✓ Code doesn't handle null user

Checking git history:
$ git log --oneline --since="1 week ago" -- src/services/user.ts

abc1234 Add user deletion feature
xyz5678 Update type definitions

$ git show abc1234

+ async function deleteUser(userId: number) {
+   await db.users.delete({ id: userId });
+ }

✓ Deletion feature added but dependent code not updated

Searching for similar patterns:
$ grep -r "db.findUser" src/

src/services/admin.ts:
const user = await db.findUser(userId);
if (!user) return null;
return user.id;

✓ Other code properly checks for null!

Hypothesis 1 confirmed.

=== STEP 4: ROOT CAUSE ===

ROOT CAUSE: getUserData doesn't handle deleted users
WHERE: src/services/user.ts:142
WHY: User deletion feature added without updating dependent code
SINCE: Commit abc1234 (March 5th, 2026)

Explanation:
When a user is deleted via the new deleteUser function,
db.findUser(userId) returns null. getUserData attempts to
access user.id without checking if user exists, causing
the TypeError.

Other parts of the codebase (e.g., admin.ts) properly
handle the null case, but this code path was missed
during the deletion feature implementation.

=== STEP 5: FIX PROPOSAL ===

FIX: Add null check before accessing user properties

CHANGES:
  src/services/user.ts:142
    Before:
      export async function getUserData(userId: number) {
        const user = await db.findUser(userId);
        return user.id;
      }
    
    After:
      export async function getUserData(userId: number) {
        const user = await db.findUser(userId);
        if (!user) return null;
        return user.id;
      }
  
  tests/services/user.test.ts:89
    Add test case:
      it('returns null for deleted user', async () => {
        const result = await getUserData(99999);
        expect(result).toBeNull();
      });

RISK: Low
- Minimal change following existing patterns
- Backward compatible (null is valid return type)
- Matches how other services handle missing users

TESTS:
1. Run existing test suite (should all pass)
2. New test: getUserData with non-existent user returns null
3. Manual: Visit profile page for deleted user, should show 404
4. Check Profile.tsx handles null return value gracefully

Waiting for approval...

User: approved

Implementing fix...
src/services/user.ts updated ✓
tests/services/user.test.ts updated ✓

Running tests...
All tests pass ✓

Fix complete!

[LEARN] Debugging: Always check git blame for recent changes in error area
[LEARN] Debugging: When adding deletion features, search for all usages
[LEARN] Convention: All db.find* calls should check for null before accessing properties

Best Practices

1

Reproduce First

Always start by confirming you can reproduce the bug. You can’t fix what you can’t see.
2

Read Stack Traces

Stack traces tell you exactly where the error occurred. Start your investigation there.
3

Check Recent Changes

Use git blame and git log to find recent changes. Regressions are often recent.
4

Form Hypotheses

Don’t randomly try fixes. Form clear hypotheses and test them systematically.
5

Find Root Cause

Don’t stop at symptoms. Find the actual root cause before proposing fixes.
6

Minimal Fixes

Propose the smallest fix that addresses the root cause. Don’t over-engineer.

Integration with Other Agents

For complex fixes, hand off to Orchestrator for multi-phase implementation. For simple fixes, implement directly then run through Reviewer.

Comparison with Other Agents

FeatureDebuggerReviewerOrchestrator
PurposeFind root causeQuality checksBuild features
TimingWhen bugs occurBefore commitDuring development
ApproachHypothesis-drivenChecklist-basedPhase-gated
OutputRoot cause + fixIssue listWorking feature
Makes changesYes (with approval)NoYes

Troubleshooting

If you can’t reproduce the error:
  • Check production logs for more context
  • Verify environment differences (data, config, versions)
  • Try with production data snapshot
  • May be intermittent—capture more occurrences
If several hypotheses seem equally likely:
  • Investigate the one with easiest test first
  • Use git blame to find recent changes
  • Check which hypothesis matches similar bugs
  • May be multiple bugs—fix one at a time
After 3 investigation rounds without clarity:
  • Debugger escalates to you with findings
  • May need domain knowledge or external context
  • Consider pair debugging session
  • Document what’s been ruled out
If the proposed fix is large or risky:
  • Hand off to Orchestrator for multi-phase implementation
  • May indicate architectural issue, not simple bug
  • Consider if this should be a refactoring task

Next Steps

Reviewer

Quality review after fixing bugs

Orchestrator

Multi-phase implementation for complex fixes

Build docs developers (and LLMs) love