bug-hunter

Bug Hunter: Debugging & Root Cause Analysis

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "bug-hunter" with this command: npx skills add xkayo32/agent-memory-orchestrator/xkayo32-agent-memory-orchestrator-bug-hunter

Bug Hunter: Debugging & Root Cause Analysis

Purpose

Systematically investigate errors, diagnose problems, identify root causes, and propose fixes through methodical debugging approaches.

When to Use This Role

✅ USE when:

  • Application presents errors

  • Unexpected behavior occurs

  • Tests fail without clear reason

  • Performance degrades

  • Need root cause analysis

❌ DO NOT USE when:

  • Implementing new feature (use implementer)

  • Error is obvious with clear fix (fix directly)

  • Writing preventive tests (use tester)

  • Design decisions needed (use architect)

Debugging Methodology

  1. Reproduction

Establish consistent reproduction steps:

Reproduction checklist:

  • Can error be reproduced consistently?

  • What are exact steps to trigger?

  • Does it happen in specific environment only?

  • Is there a stack trace or error log?

  • What changed since it last worked?

Document reproduction:

Steps to Reproduce:

  1. Start application: npm start
  2. Navigate to /login
  3. Enter valid credentials
  4. Click login button
  5. Observe: "TypeError: Cannot read property 'token' of undefined"

Environment:

  • OS: macOS 14.1
  • Node: 18.17.0
  • Browser: Chrome 120

Frequency: 100% (every login attempt)

  1. Isolation

Narrow down the problem source:

Isolation techniques:

Binary Search:

Disable half the code/features Problem still occurs? Yes: Problem is in enabled half No: Problem is in disabled half Repeat until isolated

Strategic Logging:

console.log('[DEBUG] Input:', input) console.log('[DEBUG] After transformation:', transformed) console.log('[DEBUG] Before validation:', data) console.log('[DEBUG] Final result:', result)

Debugging Tools:

// Breakpoint in code debugger; // Execution pauses here

// Conditional breakpoint if (userId === 'problematic-id') { debugger; }

Git Bisect:

Find commit that introduced bug

git bisect start git bisect bad # Current commit is broken git bisect good v1.0.0 # v1.0.0 was working

Git tests commits, you mark good/bad

Until culprit commit found

  1. Diagnosis

Analyze to find root cause:

Questions to ask:

  • What changed since last working version?

  • Which files were modified?

  • Were dependencies updated?

  • Is it logic error, state issue, or environment?

  • Are there assumptions that don't hold?

Stack Trace Analysis:

Error: Cannot read property 'name' of undefined at getUserName (user.service.ts:42) at renderProfile (profile.component.tsx:18) at onClick (button.component.tsx:10)

Analysis:

  1. Button clicked → button.component:10
  2. Calls renderProfile → profile.component:18
  3. Calls getUserName → user.service:42
  4. Tries to access user.name but user is undefined

Root Cause: getUserName() returns undefined when user not in cache Fix: Add null check or fetch user if not cached

  1. Fix & Verification

Fix root cause, not symptoms:

Fix principles:

  • Address root cause, not just symptoms

  • Add test to prevent regression

  • Document why problem occurred

  • Verify fix doesn't break anything else

Verification steps:

  • Implement fix

  • Verify original issue resolved

  • Run full test suite

  • Check for side effects

  • Test in same environment where bug occurred

Common Debugging Patterns

Pattern 1: Add Logging

// Before (mysterious failure) function processUser(userId: string) { const user = getUser(userId) return user.profile.avatar }

// After (reveals problem) function processUser(userId: string) { console.log('[DEBUG] Input userId:', userId)

const user = getUser(userId) console.log('[DEBUG] Retrieved user:', user)

if (!user) { console.error('[DEBUG] User not found!') throw new NotFoundError(User ${userId} not found) }

console.log('[DEBUG] User profile:', user.profile)

if (!user.profile) { console.error('[DEBUG] User has no profile!') throw new Error(User ${userId} has no profile) }

return user.profile.avatar }

Pattern 2: Inspect State

// Debug React state issues useEffect(() => { console.log('[STATE] userId:', userId) console.log('[STATE] user:', user) console.log('[STATE] isLoading:', isLoading) console.log('[STATE] error:', error) }, [userId, user, isLoading, error])

Pattern 3: Isolate with Unit Test

// Reproduce issue in isolated test it('should handle missing user gracefully', () => { const mockDb = { findUser: jest.fn().mockResolvedValue(null) }

const service = new UserService(mockDb)

// This should throw NotFoundError, but crashes instead expect(() => service.getUserName('missing-id')) .toThrow(NotFoundError) })

Pattern 4: Check Assumptions

// Assumption: req.user always exists after auth middleware function getProfile(req, res) { // DEBUG: Validate assumption console.assert(req.user, 'req.user should exist after auth')

if (!req.user) { console.error('[DEBUG] req.user is undefined!') console.error('[DEBUG] req.headers:', req.headers) console.error('[DEBUG] req.cookies:', req.cookies) throw new Error('User not authenticated') }

return res.json(req.user.profile) }

Debugging Tools & Techniques

Console Logging

// Structured logging console.log('[MODULE:FUNCTION] Variable:', value) console.log('[UserService:login] Credentials:', { email, hasPassword: !!password })

// Object inspection console.dir(complexObject, { depth: null })

// Table view for arrays console.table(users)

// Performance timing console.time('database-query') await db.query(...) console.timeEnd('database-query')

Debugger Statements

// Pause execution function complexCalculation(input) { debugger; // Execution pauses, can inspect variables

const step1 = transform(input) debugger; // Check step1 value

const step2 = validate(step1) debugger; // Check step2 value

return step2 }

Network Inspection

// Log HTTP requests fetch('/api/users') .then(res => { console.log('[DEBUG] Response status:', res.status) console.log('[DEBUG] Response headers:', res.headers) return res.json() }) .then(data => { console.log('[DEBUG] Response data:', data) }) .catch(error => { console.error('[DEBUG] Request failed:', error) })

Database Query Logging

// Log SQL queries db.on('query', (query) => { console.log('[DB] Query:', query.sql) console.log('[DB] Params:', query.bindings) console.log('[DB] Duration:', query.duration + 'ms') })

Example Debugging Session

Problem: "Login always fails with 'Invalid token'"

  1. Reproduction

Steps:

  1. POST /api/login with valid credentials
  2. Receive 200 OK with token
  3. POST /api/profile with token in Authorization header
  4. Receive 401 Unauthorized: "Invalid token"

Consistent: Yes, 100% reproduction

  1. Isolation

Added logging to middleware:

// auth.middleware.ts export function requireAuth(req, res, next) { console.log('[AUTH] Headers:', req.headers)

const authHeader = req.headers.authorization console.log('[AUTH] Auth header:', authHeader)

if (!authHeader) { console.log('[AUTH] No auth header!') return res.status(401).json({ error: 'No token' }) }

const token = authHeader.split(' ')[1] console.log('[AUTH] Extracted token:', token)

const decoded = verifyToken(token) console.log('[AUTH] Decoded:', decoded)

if (!decoded) { console.log('[AUTH] Token verification failed!') return res.status(401).json({ error: 'Invalid token' }) }

req.user = decoded next() }

Output:

[AUTH] Headers: { authorization: 'Bearer undefined' } [AUTH] Auth header: Bearer undefined [AUTH] Extracted token: undefined [AUTH] Decoded: null [AUTH] Token verification failed!

  1. Diagnosis

Token is undefined in Authorization header!

Checked login response:

// auth.controller.ts export async function login(req, res) { const token = generateToken(user.id, user.email) console.log('[LOGIN] Generated token:', token) // Token exists!

res.json({ message: 'Login successful', access_token: token // ← Sent as 'access_token' }) }

Checked client code:

// client.ts const response = await fetch('/api/login', { ... }) const data = await response.json()

// BUG: Looking for 'token' but server sends 'access_token' localStorage.setItem('token', data.token) // ← data.token is undefined!

Root Cause: Client expects token but server sends access_token

  1. Fix

Option A: Change server to send token (breaks other clients) Option B: Change client to read access_token (correct fix)

// client.ts - Fixed const response = await fetch('/api/login', { ... }) const data = await response.json() localStorage.setItem('token', data.access_token) // Fixed!

  1. Verification

  2. Login: ✓ Token stored correctly

  3. Profile request: ✓ Returns user data

  4. All tests: ✓ Passing

  5. No side effects: ✓ Other endpoints unaffected

  6. Prevention

Added test to prevent regression:

it('should store access_token from login response', async () => { const response = { access_token: 'test-token-123' }

// Simulate login handleLoginResponse(response)

expect(localStorage.getItem('token')).toBe('test-token-123') })

Recording Bug Fixes

Store in memory for future reference:

memory_store( project_id=current_project, type="bug_fix", title="Login token undefined issue", content=` Bug: Login always fails with "Invalid token"

Root Cause:
- Client expected 'token' field in login response
- Server sends 'access_token' field
- Mismatch caused undefined token

Solution:
- Updated client to read 'access_token' field
- Added test to prevent regression

Files Changed:
- client/auth.ts: Fixed token extraction
- client/auth.test.ts: Added regression test

Prevention:
- Test now validates response structure
- Documented API contract in README

`, metadata={ "severity": "high", "type": "authentication", "files": ["client/auth.ts", "client/auth.test.ts"] } )

Debugging Checklist

  • Error reproduced consistently

  • Reproduction steps documented

  • Stack trace analyzed

  • Recent changes reviewed

  • Problem isolated to specific code

  • Root cause identified (not just symptom)

  • Fix implemented

  • Regression test added

  • Full test suite passes

  • No new bugs introduced

  • Bug fix documented in memory

Common Bug Categories

Logic Errors

Symptoms: Wrong output, incorrect calculations Approach: Trace execution flow, check assumptions

State Issues

Symptoms: Inconsistent behavior, race conditions Approach: Log state changes, check timing

Null/Undefined Errors

Symptoms: "Cannot read property of undefined" Approach: Add null checks, validate assumptions

Async Issues

Symptoms: Timing problems, race conditions Approach: Check promise handling, add awaits

Environment Issues

Symptoms: Works locally, fails in production Approach: Check env vars, dependencies, configs

Key Principles

  • Reproduce First - Can't fix what you can't reproduce

  • Isolate Systematically - Narrow down methodically

  • Fix Root Cause - Not just symptoms

  • Add Regression Test - Prevent recurrence

  • Document Findings - Help future debugging

  • Verify Thoroughly - Ensure no side effects

  • Learn from Bugs - Update practices to prevent similar issues

Summary

As debugger:

  • Reproduce issues consistently

  • Isolate problems systematically

  • Analyze to find root cause

  • Fix cause, not symptoms

  • Add tests to prevent regression

  • Document findings in memory

  • Verify fixes thoroughly

Focus on methodical investigation, root cause analysis, and preventive measures for effective debugging.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-implementer

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

bug-hunter

No summary provided by upstream source.

Repository SourceNeeds Review
General

bug-hunter

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

bug-hunter

No summary provided by upstream source.

Repository SourceNeeds Review