Claude Agent Skill · by Wshobson

Debugging Strategies

When you're staring at a stack trace at 2 AM wondering why your code works locally but crashes in production, this skill walks you through systematic debugging

Install
Terminal · npx
$npx skills add https://github.com/wshobson/agents --skill debugging-strategies
Works with Paperclip

How Debugging Strategies fits into a Paperclip company.

Debugging Strategies drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md527 lines
Expand
---name: debugging-strategiesdescription: Master systematic debugging techniques, profiling tools, and root cause analysis to efficiently track down bugs across any codebase or technology stack. Use when investigating bugs, performance issues, or unexpected behavior.--- # Debugging Strategies Transform debugging from frustrating guesswork into systematic problem-solving with proven strategies, powerful tools, and methodical approaches. ## When to Use This Skill - Tracking down elusive bugs- Investigating performance issues- Understanding unfamiliar codebases- Debugging production issues- Analyzing crash dumps and stack traces- Profiling application performance- Investigating memory leaks- Debugging distributed systems ## Core Principles ### 1. The Scientific Method **1. Observe**: What's the actual behavior?**2. Hypothesize**: What could be causing it?**3. Experiment**: Test your hypothesis**4. Analyze**: Did it prove/disprove your theory?**5. Repeat**: Until you find the root cause ### 2. Debugging Mindset **Don't Assume:** - "It can't be X" - Yes it can- "I didn't change Y" - Check anyway- "It works on my machine" - Find out why **Do:** - Reproduce consistently- Isolate the problem- Keep detailed notes- Question everything- Take breaks when stuck ### 3. Rubber Duck Debugging Explain your code and problem out loud (to a rubber duck, colleague, or yourself). Often reveals the issue. ## Systematic Debugging Process ### Phase 1: Reproduce ```markdown## Reproduction Checklist 1. **Can you reproduce it?**   - Always? Sometimes? Randomly?   - Specific conditions needed?   - Can others reproduce it? 2. **Create minimal reproduction**   - Simplify to smallest example   - Remove unrelated code   - Isolate the problem 3. **Document steps**   - Write down exact steps   - Note environment details   - Capture error messages``` ### Phase 2: Gather Information ```markdown## Information Collection 1. **Error Messages**   - Full stack trace   - Error codes   - Console/log output 2. **Environment**   - OS version   - Language/runtime version   - Dependencies versions   - Environment variables 3. **Recent Changes**   - Git history   - Deployment timeline   - Configuration changes 4. **Scope**   - Affects all users or specific ones?   - All browsers or specific ones?   - Production only or also dev?``` ### Phase 3: Form Hypothesis ```markdown## Hypothesis Formation Based on gathered info, ask: 1. **What changed?**   - Recent code changes   - Dependency updates   - Infrastructure changes 2. **What's different?**   - Working vs broken environment   - Working vs broken user   - Before vs after 3. **Where could this fail?**   - Input validation   - Business logic   - Data layer   - External services``` ### Phase 4: Test & Verify ```markdown## Testing Strategies 1. **Binary Search**   - Comment out half the code   - Narrow down problematic section   - Repeat until found 2. **Add Logging**   - Strategic console.log/print   - Track variable values   - Trace execution flow 3. **Isolate Components**   - Test each piece separately   - Mock dependencies   - Remove complexity 4. **Compare Working vs Broken**   - Diff configurations   - Diff environments   - Diff data``` ## Debugging Tools ### JavaScript/TypeScript Debugging ```typescript// Chrome DevTools Debuggerfunction processOrder(order: Order) {  debugger; // Execution pauses here   const total = calculateTotal(order);  console.log("Total:", total);   // Conditional breakpoint  if (order.items.length > 10) {    debugger; // Only breaks if condition true  }   return total;} // Console debugging techniquesconsole.log("Value:", value); // Basicconsole.table(arrayOfObjects); // Table formatconsole.time("operation");/* code */ console.timeEnd("operation"); // Timingconsole.trace(); // Stack traceconsole.assert(value > 0, "Value must be positive"); // Assertion // Performance profilingperformance.mark("start-operation");// ... operation codeperformance.mark("end-operation");performance.measure("operation", "start-operation", "end-operation");console.log(performance.getEntriesByType("measure"));``` **VS Code Debugger Configuration:** ```json// .vscode/launch.json{  "version": "0.2.0",  "configurations": [    {      "type": "node",      "request": "launch",      "name": "Debug Program",      "program": "${workspaceFolder}/src/index.ts",      "preLaunchTask": "tsc: build - tsconfig.json",      "outFiles": ["${workspaceFolder}/dist/**/*.js"],      "skipFiles": ["<node_internals>/**"]    },    {      "type": "node",      "request": "launch",      "name": "Debug Tests",      "program": "${workspaceFolder}/node_modules/jest/bin/jest",      "args": ["--runInBand", "--no-cache"],      "console": "integratedTerminal"    }  ]}``` ### Python Debugging ```python# Built-in debugger (pdb)import pdb def calculate_total(items):    total = 0    pdb.set_trace()  # Debugger starts here     for item in items:        total += item.price * item.quantity     return total # Breakpoint (Python 3.7+)def process_order(order):    breakpoint()  # More convenient than pdb.set_trace()    # ... code # Post-mortem debuggingtry:    risky_operation()except Exception:    import pdb    pdb.post_mortem()  # Debug at exception point # IPython debugging (ipdb)from ipdb import set_traceset_trace()  # Better interface than pdb # Logging for debuggingimport logginglogging.basicConfig(level=logging.DEBUG)logger = logging.getLogger(__name__) def fetch_user(user_id):    logger.debug(f'Fetching user: {user_id}')    user = db.query(User).get(user_id)    logger.debug(f'Found user: {user}')    return user # Profile performanceimport cProfileimport pstats cProfile.run('slow_function()', 'profile_stats')stats = pstats.Stats('profile_stats')stats.sort_stats('cumulative')stats.print_stats(10)  # Top 10 slowest``` ### Go Debugging ```go// Delve debugger// Install: go install github.com/go-delve/delve/cmd/dlv@latest// Run: dlv debug main.go import (    "fmt"    "runtime"    "runtime/debug") // Print stack tracefunc debugStack() {    debug.PrintStack()} // Panic recovery with debuggingfunc processRequest() {    defer func() {        if r := recover(); r != nil {            fmt.Println("Panic:", r)            debug.PrintStack()        }    }()     // ... code that might panic} // Memory profilingimport _ "net/http/pprof"// Visit http://localhost:6060/debug/pprof/ // CPU profilingimport (    "os"    "runtime/pprof") f, _ := os.Create("cpu.prof")pprof.StartCPUProfile(f)defer pprof.StopCPUProfile()// ... code to profile``` ## Advanced Debugging Techniques ### Technique 1: Binary Search Debugging ```bash# Git bisect for finding regressiongit bisect startgit bisect bad                    # Current commit is badgit bisect good v1.0.0            # v1.0.0 was good # Git checks out middle commit# Test it, then:git bisect good   # if it worksgit bisect bad    # if it's broken # Continue until bug foundgit bisect reset  # when done``` ### Technique 2: Differential Debugging Compare working vs broken: ```markdown## What's Different? | Aspect       | Working     | Broken         || ------------ | ----------- | -------------- || Environment  | Development | Production     || Node version | 18.16.0     | 18.15.0        || Data         | Empty DB    | 1M records     || User         | Admin       | Regular user   || Browser      | Chrome      | Safari         || Time         | During day  | After midnight | Hypothesis: Time-based issue? Check timezone handling.``` ### Technique 3: Trace Debugging ```typescript// Function call tracingfunction trace(  target: any,  propertyKey: string,  descriptor: PropertyDescriptor,) {  const originalMethod = descriptor.value;   descriptor.value = function (...args: any[]) {    console.log(`Calling ${propertyKey} with args:`, args);    const result = originalMethod.apply(this, args);    console.log(`${propertyKey} returned:`, result);    return result;  };   return descriptor;} class OrderService {  @trace  calculateTotal(items: Item[]): number {    return items.reduce((sum, item) => sum + item.price, 0);  }}``` ### Technique 4: Memory Leak Detection ```typescript// Chrome DevTools Memory Profiler// 1. Take heap snapshot// 2. Perform action// 3. Take another snapshot// 4. Compare snapshots // Node.js memory debuggingif (process.memoryUsage().heapUsed > 500 * 1024 * 1024) {  console.warn("High memory usage:", process.memoryUsage());   // Generate heap dump  require("v8").writeHeapSnapshot();} // Find memory leaks in testslet beforeMemory: number; beforeEach(() => {  beforeMemory = process.memoryUsage().heapUsed;}); afterEach(() => {  const afterMemory = process.memoryUsage().heapUsed;  const diff = afterMemory - beforeMemory;   if (diff > 10 * 1024 * 1024) {    // 10MB threshold    console.warn(`Possible memory leak: ${diff / 1024 / 1024}MB`);  }});``` ## Debugging Patterns by Issue Type ### Pattern 1: Intermittent Bugs ```markdown## Strategies for Flaky Bugs 1. **Add extensive logging**   - Log timing information   - Log all state transitions   - Log external interactions 2. **Look for race conditions**   - Concurrent access to shared state   - Async operations completing out of order   - Missing synchronization 3. **Check timing dependencies**   - setTimeout/setInterval   - Promise resolution order   - Animation frame timing 4. **Stress test**   - Run many times   - Vary timing   - Simulate load``` ### Pattern 2: Performance Issues ```markdown## Performance Debugging 1. **Profile first**   - Don't optimize blindly   - Measure before and after   - Find bottlenecks 2. **Common culprits**   - N+1 queries   - Unnecessary re-renders   - Large data processing   - Synchronous I/O 3. **Tools**   - Browser DevTools Performance tab   - Lighthouse   - Python: cProfile, line_profiler   - Node: clinic.js, 0x``` ### Pattern 3: Production Bugs ```markdown## Production Debugging 1. **Gather evidence**   - Error tracking (Sentry, Bugsnag)   - Application logs   - User reports   - Metrics/monitoring 2. **Reproduce locally**   - Use production data (anonymized)   - Match environment   - Follow exact steps 3. **Safe investigation**   - Don't change production   - Use feature flags   - Add monitoring/logging   - Test fixes in staging``` ## Best Practices 1. **Reproduce First**: Can't fix what you can't reproduce2. **Isolate the Problem**: Remove complexity until minimal case3. **Read Error Messages**: They're usually helpful4. **Check Recent Changes**: Most bugs are recent5. **Use Version Control**: Git bisect, blame, history6. **Take Breaks**: Fresh eyes see better7. **Document Findings**: Help future you8. **Fix Root Cause**: Not just symptoms ## Common Debugging Mistakes - **Making Multiple Changes**: Change one thing at a time- **Not Reading Error Messages**: Read the full stack trace- **Assuming It's Complex**: Often it's simple- **Debug Logging in Prod**: Remove before shipping- **Not Using Debugger**: console.log isn't always best- **Giving Up Too Soon**: Persistence pays off- **Not Testing the Fix**: Verify it actually works ## Quick Debugging Checklist ```markdown## When Stuck, Check: - [ ] Spelling errors (typos in variable names)- [ ] Case sensitivity (fileName vs filename)- [ ] Null/undefined values- [ ] Array index off-by-one- [ ] Async timing (race conditions)- [ ] Scope issues (closure, hoisting)- [ ] Type mismatches- [ ] Missing dependencies- [ ] Environment variables- [ ] File paths (absolute vs relative)- [ ] Cache issues (clear cache)- [ ] Stale data (refresh database)```