Claude
Skills
Sign in
Back

debug

Included with Lifetime
$97 forever

Investigate and diagnose issues without necessarily fixing them

Code Review

What this skill does


# Debugging Skill

Systematic approaches to investigating and diagnosing bugs.

## Core Principle

**Understand before fixing.** A proper diagnosis leads to a proper fix.

## Name

han-core:debug - Investigate and diagnose issues without necessarily fixing them

## Synopsis

```
/debug [arguments]
```

## Debug vs Fix

**Use `/debug` when:**

- Investigating an issue to understand it
- Need to gather information before fixing
- Want to identify root cause without implementing solution
- Triaging to determine severity/priority
- Research phase before fix

**Use `/fix` when:**

- Ready to implement the solution
- Debugging AND fixing in one go
- Issue is understood, just needs fixing

## The Scientific Method for Debugging

### 1. Observe

**Gather all the facts:**

- What's the symptom? (What's happening that shouldn't?)
- When does it happen? (Always, sometimes, specific conditions?)
- Who's affected? (All users, some users, specific scenarios?)
- Error messages? (Exact text, stack traces, error codes?)
- Recent changes? (What changed before this started?)

**Evidence to collect:**

- Error messages and stack traces
- Application logs
- User reports
- Reproduction steps
- Environment details (browser, OS, versions)
- Network requests/responses
- Database query logs

### 2. Form Hypothesis

**Based on symptoms, what could cause this?**

**Common categories:**

- **Logic error:** Code does wrong thing
- **State management:** State gets out of sync
- **Async/timing:** Race condition, callback hell
- **Data issue:** Unexpected input format
- **Integration:** API change, service down
- **Environment:** Config, permissions, network
- **Resource:** Memory leak, connection pool exhausted

**Prioritize hypotheses:**

1. Most likely causes first
2. Easiest to test first (when equal likelihood)
3. Most impactful if true

### 3. Test Hypothesis

**Design experiment to prove/disprove:**

- Add logging to see values
- Add breakpoints to pause execution
- Modify input to isolate variable
- Disable feature to rule out
- Compare with working version

**Keep notes:**

```markdown
**Hypothesis:** Database query timeout
**Test:** Add query timing logs
**Result:** Query completes in 50ms
**Conclusion:** Not the database

**Hypothesis:** Network latency
**Test:** Check network tab, add timing
**Result:** API call takes 5 seconds
**Conclusion:** Found the issue
```

### 4. Analyze Results

**What did you learn?**

- Hypothesis confirmed or rejected?
- New questions raised?
- Unexpected findings?
- Root cause identified?

### 5. Repeat or Conclude

**If root cause found:**

- Document findings
- Estimate impact
- Plan fix

**If not found:**

- Form new hypothesis
- Repeat cycle

## Debugging Strategies

### Strategy 1: Add Logging

**Most universally useful technique:**

```typescript
// Strategic console.log placement
function processOrder(order) {
  console.log('processOrder START:', { orderId: order.id })

  const items = order.items
  console.log('items:', items.length)

  const validated = validate(items)
  console.log('validation result:', validated)

  if (!validated.success) {
    console.log('validation failed:', validated.errors)
    throw new Error('Invalid order')
  }

  const total = calculateTotal(items)
  console.log('total calculated:', total)

  console.log('processOrder END')
  return total
}
```

**Logging guidelines:**

- Log function entry/exit
- Log branching decisions
- Log external calls (API, database)
- Log unexpected values
- Include context (IDs, user info)

### Strategy 2: Use Debugger

**Interactive debugging:**

```typescript
// Browser
function buggyFunction(input) {
  debugger;  // Execution pauses here
  const result = transform(input)
  debugger;  // And here
  return result
}

// Node.js
node --inspect app.js
# Then open chrome://inspect in Chrome
```

**Debugger features:**

- Step over (next line)
- Step into (into function call)
- Step out (back to caller)
- Watch expressions
- Call stack inspection
- Variable inspection

### Strategy 3: Binary Search

**Isolate the problem area:**

```typescript
// 100 lines of code, bug somewhere

// Comment out lines 50-100
// Bug still happens? It's in lines 1-50

// Comment out lines 25-50
// Bug disappears? It's in lines 25-50

// Comment out lines 37-50
// Bug still happens? It's in lines 25-37

// Continue until isolated to specific lines
```

### Strategy 4: Rubber Duck Debugging

**Explain the problem out loud:**

1. "This function is supposed to calculate shipping cost"
2. "It takes the weight and destination"
3. "First it... wait, it's using price instead of weight!"
4. *(Bug found)*

**Why this works:** Forces you to examine assumptions.

### Strategy 5: Compare Working vs Broken

**What's different?**

**Version comparison:**

```bash
# Find which commit broke it
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# Git checks out middle commit
npm test
git bisect good/bad
# Repeat until found
```

**Environment comparison:**

- Works locally but not production?
- Works for some users but not others?
- Worked yesterday but not today?

**What changed?**

### Strategy 6: Simplify

**Reduce to minimal reproduction:**

```typescript
// Complex case with bug
processUserOrderWithDiscountsAndShipping(user, cart, promo, address)

// Simplify inputs one at a time
processUserOrderWithDiscountsAndShipping(user, [], null, null)
// Still breaks? Not discount or address

processUserOrderWithDiscountsAndShipping(null, [], null, null)
// Works now? It's the user object

// What about the user object causes it?
```

### Strategy 7: Check Assumptions

**Question everything:**

```typescript
// Assumption: API returns array
const users = await api.getUsers()
users.forEach(...)  // Crashes

// Check assumption
console.log(typeof users)  // "undefined"
console.log(users)          // undefined

// Assumption was wrong!
```

**Common wrong assumptions:**

- Function returns expected type
- Variable is defined
- Array is not empty
- API will always respond
- Async operation has completed
- State is up to date

## Debugging by Symptom

### "Intermittent failure"

**Likely causes:**

- Race condition (timing-dependent)
- Data-dependent (certain inputs trigger it)
- Resource leak (happens after N operations)
- External service flakiness

**Investigation:**

- Add extensive logging
- Look for async operations
- Check timing between operations
- Look for shared state
- Run many times to see pattern

### "Works locally, fails in production"

**Check differences:**

- Environment variables
- Data (production has different/more data)
- Network (CORS, SSL, proxies)
- Dependencies (versions, OS)
- Resources (memory, connections)

### "Slow performance"

**Don't guess - profile:**

**Frontend:**

- Chrome DevTools > Performance tab
- Look for long tasks (> 50ms)
- Check for layout thrashing
- Look for memory leaks

**Backend:**

- Add timing logs around operations
- Check database query time (EXPLAIN ANALYZE)
- Check external API call time
- Profile with APM tool

### "Memory leak"

**Investigation:**

```typescript
// Take heap snapshot
// Do operation that leaks
// Take another heap snapshot
// Compare - what increased?
```

**Common causes:**

- Event listeners not removed
- Closures holding references
- Global variables accumulating
- Intervals not cleared
- Cache growing unbounded

### "Crash/Exception"

**Read the stack trace:**

```
Error: Cannot read property 'map' of undefined
    at processUsers (app.js:42:15)
    at handleRequest (app.js:23:3)
    at Server.<anonymous> (server.js:12:5)
```

**Stack trace tells you:**

- Line 42: Where it crashed
- Line 23: Where it was called from
- Line 12: Origin of the request

**Then:**

- Go to line 42
- Check what's undefined
- Trace back why it's undefined

### "It works sometimes"

- Race condition?
- Timing issue?
- Data-dependent?
- Check for async issues

## Common Bug Patterns

### Null/Undefined

```typescript
// Bug
function process(user) {
  return user

Related in Code Review