Skip to content

Debugging, Testing & Troubleshooting Mastery

Professional debugging and testing strategies with Claude Code CLI.

What You'll Learn

  • Systematic debugging methodology
  • Test-driven development with Claude CLI
  • Production troubleshooting patterns
  • Performance debugging
  • Error analysis and resolution

The Debugging Mindset

Effective debugging with Claude Code CLI follows a systematic approach:

┌─────────────────────────────────────────────────────────────┐
│                  DEBUGGING METHODOLOGY                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. OBSERVE    →   2. HYPOTHESIZE   →   3. TEST            │
│  What exactly     What could cause     Verify with          │
│  is happening?    this behavior?       evidence             │
│                                                              │
│  4. ISOLATE    →   5. FIX           →   6. VERIFY          │
│  Narrow down       Implement the       Confirm fix,         │
│  the source        solution            no regressions       │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Providing Context to Claude CLI

The Gold Standard Error Report

When debugging, give Claude CLI complete information:

> I'm getting this error:

  TypeError: Cannot read property 'id' of undefined
    at UserService.getProfile (src/services/user.ts:45:23)
    at UserController.show (src/controllers/user.ts:23:30)
    at Router.handle (/node_modules/express/lib/router/index.js:174:3)

  This happens when:
  - User is logged in
  - They visit /profile
  - But only sometimes (maybe 1 in 10 requests)

  Expected: Profile page loads
  Actual: 500 error

  Recent changes:
  - Added caching to user lookup yesterday
  - No changes to the profile route

Structured Debugging Session

> Debug mode: I'll share information step by step.

  Error: User profile fails to load
  Frequency: Intermittent (10% of requests)
  Started: After yesterday's deploy

  Let's investigate systematically.

Common Bug Patterns

Pattern 1: Null/Undefined Errors

> This function throws "Cannot read property 'email' of undefined":

  async function sendWelcomeEmail(userId: string) {
    const user = await db.users.findById(userId);
    await mailer.send(user.email, 'Welcome!');
  }

  The userId is always valid. Why might user be undefined?

Claude CLI will: 1. Check if findById can return undefined 2. Examine database queries 3. Look for race conditions 4. Suggest defensive coding

Pattern 2: Async/Timing Issues

> This test passes locally but fails in CI:

  test('should update user', async () => {
    await updateUser(userId, { name: 'New Name' });
    const user = await getUser(userId);
    expect(user.name).toBe('New Name');
  });

  Error: Expected "New Name", got "Old Name"

Claude CLI checks for: - Missing await statements - Database transaction timing - Cache invalidation issues - Test isolation problems

Pattern 3: State Management Bugs

> React component shows stale data:

  function UserProfile({ userId }) {
    const [user, setUser] = useState(null);

    useEffect(() => {
      fetchUser(userId).then(setUser);
    }, []);  // <-- dependency array

    return <div>{user?.name};
  }

  When userId changes, it still shows the old user.

Pattern 4: Race Conditions

> Sometimes get duplicate entries in the database:

  async function createOrder(userId, items) {
    const existing = await db.orders.findPending(userId);
    if (!existing) {
      return await db.orders.create({ userId, items });
    }
    return existing;
  }

  Two orders appear when user double-clicks submit.

Test-Driven Development with Claude CLI

TDD Workflow

> I'm implementing a password validator. Let's do TDD.

  Requirements:
  - Minimum 8 characters
  - At least one uppercase
  - At least one lowercase
  - At least one number
  - At least one special character

  Start by writing the tests.

Claude CLI creates comprehensive tests first:

// password-validator.test.ts
describe('validatePassword', () => {
  describe('length requirements', () => {
    it('should reject passwords shorter than 8 characters', () => {
      expect(validatePassword('Abc1!@#')).toBe(false);  // 7 chars
    });

    it('should accept passwords of exactly 8 characters', () => {
      expect(validatePassword('Abcd1!@#')).toBe(true);  // 8 chars
    });
  });

  describe('character requirements', () => {
    it('should require at least one uppercase letter', () => {
      expect(validatePassword('abcd1!@#9')).toBe(false);
    });

    // ... more tests
  });

  describe('edge cases', () => {
    it('should handle empty string', () => {
      expect(validatePassword('')).toBe(false);
    });

    it('should handle unicode characters', () => {
      expect(validatePassword('Über1!@#')).toBe(true);
    });
  });
});

Then implement:

> Run the tests and implement the function to make them pass.

Test Coverage Analysis

> Analyze test coverage for the auth module.
  - Which functions are untested?
  - Which branches are not covered?
  - What edge cases are missing?

Writing Tests for Existing Code

> Write comprehensive tests for src/services/payment.ts
  - Cover all public methods
  - Include error scenarios
  - Mock external dependencies
  - Follow existing test patterns in this project

Debugging Strategies

> The bug was introduced sometime in the last 20 commits.
  Let's use git bisect to find when.

  Good commit: abc123 (2 weeks ago, release 1.5)
  Bad commit: HEAD

  Guide me through the bisect process.

Strategy 2: Isolation

> This API endpoint is slow. Let's isolate the bottleneck.

  Current time breakdown:
  - Total request: 2.5 seconds

  Help me add timing to each step:
  1. Request parsing
  2. Authentication
  3. Database queries
  4. Business logic
  5. Response serialization

Strategy 3: Reproduction

> I can't reproduce this bug locally.

  Error from production logs:
  [error message]

  Environment differences:
  - Prod: PostgreSQL 14, Node 18, Redis cluster
  - Local: PostgreSQL 13, Node 20, Redis single

  Help me create a reproduction case.

Strategy 4: Rubber Duck Debugging

> Let me explain this bug to you step by step.
  Stop me when you spot the issue.

  1. User clicks "Submit Order"
  2. Frontend sends POST to /api/orders
  3. Backend validates the cart...
  [continue explaining]

Production Troubleshooting

Log Analysis

> Analyze these production logs:

  [paste logs]

  Find:
  1. Error patterns
  2. Timing anomalies
  3. User impact scope
  4. Root cause indicators

Memory Leak Investigation

> The application's memory usage grows over time:

  Hour 1: 250MB
  Hour 4: 450MB
  Hour 8: 800MB
  Hour 12: Crash (OOM)

  Here's a heap snapshot comparison: [paste]

  Identify the leak source.

Performance Profiling

> This query is slow in production:

  SELECT * FROM orders
  WHERE user_id = ?
  AND status = 'pending'
  ORDER BY created_at DESC;

  Execution time: 2.3 seconds
  Table has 5 million rows

  Analyze and suggest indexes.

Incident Response

> Production incident: API returning 503 errors

  Current status:
  - Error rate: 45%
  - Started: 10 minutes ago
  - No recent deploys

  Recent events:
  - Traffic spike from marketing campaign
  - Database CPU at 95%

  Guide me through triage and mitigation.

Testing Best Practices

Test Structure

> Review our test structure and suggest improvements:

  tests/
  ├── unit/
  ├── integration/
  └── e2e/

  Current issues:
  - Tests are slow (5 minutes)
  - Flaky tests in CI
  - Hard to run single tests

Mocking Strategy

> What's the right mocking strategy for this service?

  UserService depends on:
  - Database (Prisma)
  - Email service (SendGrid)
  - Cache (Redis)
  - External API (Stripe)

  Help me create proper mocks that:
  1. Are maintainable
  2. Don't hide real bugs
  3. Run fast

Snapshot Testing

> Should we use snapshot tests for our React components?

  Current situation:
  - 50 components
  - Frequent UI changes
  - Small team

  Give me pros/cons for our case.

Integration Test Design

> Design integration tests for the checkout flow:

  1. Add items to cart
  2. Apply discount code
  3. Enter shipping info
  4. Process payment
  5. Send confirmation

  Consider:
  - Test data setup
  - External service mocking
  - Cleanup after tests

Debugging CLI Commands

Quick Debug Helpers

# Add to your shell config

# Quick error lookup
debug-error() {
  claude -p "Explain this error and common solutions: $*"
}

# Test failure analysis
debug-test() {
  npm test 2>&1 | claude -p "Analyze these test results and suggest fixes for failures"
}

# Log analysis
debug-logs() {
  tail -100 "$1" | claude -p "Analyze these logs for errors and issues"
}

# Stack trace analysis
debug-stack() {
  claude -p "Analyze this stack trace and identify the root cause: $(cat)"
}

# Usage:
# debug-error "TypeError: Cannot read property 'foo' of undefined"
# debug-test
# debug-logs /var/log/app.log
# cat error.log | debug-stack

Interactive Debugging Session

# Start a focused debugging session
alias debug-session='claude "I need to debug an issue. I will provide information step by step. Ask me questions to help isolate the problem."'

Error Handling Patterns

Defensive Coding

> Review error handling in src/services and suggest improvements:

  Look for:
  1. Unhandled promise rejections
  2. Missing null checks
  3. Swallowed errors
  4. Improper error propagation
  5. Missing error context

Error Boundaries

> Design an error handling strategy for our Express API:

  Requirements:
  - Consistent error response format
  - Proper HTTP status codes
  - Error logging with context
  - No sensitive data leakage
  - Client-friendly messages

Graceful Degradation

> The payment service occasionally times out.
  Design graceful degradation:

  - User should see helpful message
  - Order should be recoverable
  - Support should be notified
  - Metrics should track failures

Troubleshooting Checklist

Before Asking Claude CLI

## Debug Information Checklist

- [ ] Exact error message and stack trace
- [ ] Steps to reproduce
- [ ] Expected vs actual behavior
- [ ] Environment details (OS, Node version, etc.)
- [ ] Recent changes (code, config, infrastructure)
- [ ] Frequency (always, sometimes, once)
- [ ] Scope (all users, specific users, specific data)

Systematic Investigation

> Help me investigate systematically. Don't jump to conclusions.

  Issue: [describe]

  Let's:
  1. List all possible causes
  2. Rank by likelihood
  3. Design tests for each hypothesis
  4. Eliminate causes one by one

Try It Yourself

Exercise 1: Debug a Tricky Bug

Create a file with a subtle bug and practice debugging:

# Create buggy code
claude "Create a JavaScript file with a subtle async race condition bug that only manifests sometimes"

# Try to find it
claude "Debug this file - there's a race condition somewhere"

Exercise 2: TDD Practice

# Start with requirements
claude "Let's practice TDD. Give me requirements for a URL shortener. Don't write any implementation yet."

# Write tests first
claude "Write comprehensive tests for these requirements"

# Implement to pass tests
claude "Now implement the URL shortener to pass all tests"

Exercise 3: Production Debugging

# Simulate production logs
claude "Generate realistic production error logs for a Node.js API with various issues"

# Practice analysis
claude "Analyze these logs and identify all issues, ranked by severity"

What's Next?

Learn advanced CLI techniques in 08-cli-power-user.


Summary: - Follow systematic methodology: Observe → Hypothesize → Test → Isolate → Fix → Verify - Provide complete context: error, stack trace, steps, environment, recent changes - Use TDD: Write tests first, implement to pass, refactor - Common patterns: null checks, async issues, race conditions, state bugs - Production debugging: Log analysis, profiling, incident response - Create CLI helpers for common debugging tasks - Always verify fixes don't introduce regressions


Learning Resources

GitHub: TDD & Debugging with AI (Official GitHub channel)

Advanced debugging - systematic methodology, TDD workflows, and production troubleshooting.

Additional Resources

Type Resource Description
🎬 Video Claude Code Debug Mastery Edmund Yong - Advanced debugging
📚 Official Docs Troubleshooting Official debugging guide
📖 Tutorial TDD with AI AI-powered TDD patterns
🎓 Free Course Microsoft Debug Course Free 10-hour course
💼 Commercial GitHub Copilot Pro Advanced debug techniques