| name | debug |
| description | Investigate and diagnose issues without necessarily fixing them |
| allowed-tools | ["Read","Write","Edit","Bash","Grep","Glob"] |
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:
- Most likely causes first
- Easiest to test first (when equal likelihood)
- 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:
**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:
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:
function buggyFunction(input) {
debugger;
const result = transform(input)
debugger;
return result
}
node --inspect app.js
# Then open 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:
Strategy 4: Rubber Duck Debugging
Explain the problem out loud:
- "This function is supposed to calculate shipping cost"
- "It takes the weight and destination"
- "First it... wait, it's using price instead of weight!"
- (Bug found)
Why this works: Forces you to examine assumptions.
Strategy 5: Compare Working vs Broken
What's different?
Version comparison:
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
npm test
git bisect good/bad
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:
processUserOrderWithDiscountsAndShipping(user, cart, promo, address)
processUserOrderWithDiscountsAndShipping(user, [], null, null)
processUserOrderWithDiscountsAndShipping(null, [], null, null)
Strategy 7: Check Assumptions
Question everything:
const users = await api.getUsers()
users.forEach(...)
console.log(typeof users)
console.log(users)
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:
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
function process(user) {
return user.name.toUpperCase()
}
console.log('user:', user)
Off-by-One
for (let i = 0; i <= array.length; i++) {
process(array[i])
}
console.log('i:', i, 'length:', array.length)
Async Timing
let data
fetchData().then(result => {
data = result
})
console.log(data)
console.log('1. Before fetch')
fetchData().then(result => {
console.log('3. Got result')
data = result
})
console.log('2. After fetch call')
State Mutation
function addItem(cart, item) {
cart.items.push(item)
return cart
}
const originalCart = { items: [] }
const newCart = addItem(originalCart, item)
console.log('before:', originalCart)
const newCart = addItem(originalCart, item)
console.log('after:', originalCart)
Scope Issues
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100)
}
Investigation Report Format
## Investigation: [Issue description]
### Symptoms
[What's happening that's wrong?]
### Evidence
- Error message: [exact text]
- When it happens: [conditions]
- Frequency: [always/sometimes/rarely]
- Affected users: [all/some/specific group]
### Reproduction Steps
1. [Step 1]
2. [Step 2]
3. [Observe error]
### Investigation Timeline
**Hypothesis 1:** [What I thought might be wrong]
- Tested by: [What I did to test]
- Result: [What I found]
- Conclusion: [Ruled out / Confirmed]
**Hypothesis 2:** [Next theory]
- Tested by: [What I did]
- Result: [What I found]
- Conclusion: [Ruled out / Confirmed]
### Root Cause
[What's actually causing the issue]
**Evidence:**
- [Log showing the problem]
- [Stack trace pointing to source]
- [Data showing the pattern]
### Impact
- Severity: [Critical/High/Medium/Low]
- Scope: [How many users/scenarios affected]
- Workaround: [Any temporary solutions]
### Next Steps
- [ ] [What should be done to fix]
- [ ] [Any additional investigation needed]
- [ ] [Related issues to check]
Debugging Tools
Browser Developer Tools
Console:
console.log() - Print values
console.table() - Display arrays/objects as table
console.trace() - Print stack trace
console.time() / console.timeEnd() - Measure duration
Debugger:
- Set breakpoints
- Step through code
- Inspect variables
- Watch expressions
- Call stack
Network:
- View all requests
- See request/response headers and bodies
- Measure timing
- Replay requests
Performance:
- Record profile
- See function call tree
- Identify bottlenecks
- Check memory usage
Command Line Tools
grep -r "error" logs/
tail -f logs/app.log
grep -B 5 -A 5 "ERROR" logs/app.log
df -h
free -m
ps aux | grep node
Database Debugging
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;
SELECT pg_size_pretty(pg_total_relation_size('users'));
\d users
Debugging Checklist
Before Starting
During Investigation
After Finding Root Cause
Anti-Patterns
Random Code Changes
BAD: "Maybe if I change this... nope, try this... nope, try this..."
GOOD: "Hypothesis: X causes Y. Test: Change X. Result: Y still happens.
Conclusion: X is not the cause."
Assuming Without Verifying
BAD: "The API must be returning valid data"
GOOD: "Let me log the API response to see what it actually returns"
Stopping at Symptoms
BAD: "The page is blank. Fixed by adding a null check."
GOOD: "The page is blank because user is null. User is null because
authentication token expired. Root cause: token not being refreshed."
Debugging in Production
BAD: "Let me add console.log to production to see..."
GOOD: "Let me reproduce locally and debug there, or use proper logging"
No Reproduction Steps
BAD: "It crashed once, let me guess why"
GOOD: "Let me find reliable way to reproduce it first"
Examples
When the user says:
- "Why is this page loading slowly?"
- "Investigate this intermittent test failure"
- "Figure out why users are seeing this error"
- "Debug the memory leak in production"
- "What's causing the database timeouts?"
Integration with Other Skills
- Use proof-of-work skill to document evidence
- Use test-driven-development skill to add regression test after fix
- Use explain skill when explaining bug to others
- Use boy-scout-rule skill while fixing (improve surrounding code)
Notes
- Use TaskCreate to track investigation steps
- Document findings even if not fixing immediately
- Create minimal reproduction case
- Consider using /fix once root cause is found
- Add logging/metrics to prevent future issues
Remember
- Reproduce first - If you can't reproduce, you can't debug
- Gather evidence - Don't guess, look at data
- Form hypothesis - What do you think is wrong?
- Test systematically - Prove or disprove hypothesis
- Find root cause - Not just symptoms
- Document - Help future you and others
Debugging is detective work. Be methodical, not random.