Loading...
Loading...
Investigate and diagnose issues without necessarily fixing them
npx skill4agent add thebushidocollective/han debug/debug [arguments]/debug/fix**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// 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
}// 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// 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# 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// 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?// 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!// Take heap snapshot
// Do operation that leaks
// Take another heap snapshot
// Compare - what increased?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)// Bug
function process(user) {
return user.name.toUpperCase() // Crashes if user is null
}
// Investigation
console.log('user:', user) // undefined - why?
// Trace back to where user comes from// Bug
for (let i = 0; i <= array.length; i++) { // <= instead of <
process(array[i]) // Crashes on last iteration
}
// Investigation
console.log('i:', i, 'length:', array.length)
// Notice i === array.length causes array[i] === undefined// Bug
let data
fetchData().then(result => {
data = result
})
console.log(data) // undefined - async not complete
// Investigation
console.log('1. Before fetch')
fetchData().then(result => {
console.log('3. Got result')
data = result
})
console.log('2. After fetch call')
// Output: 1, 2, 3 - async completes later// Bug
function addItem(cart, item) {
cart.items.push(item) // Mutates input!
return cart
}
const originalCart = { items: [] }
const newCart = addItem(originalCart, item)
// originalCart was modified - unexpected!
// Investigation
console.log('before:', originalCart)
const newCart = addItem(originalCart, item)
console.log('after:', originalCart) // Changed!// Bug
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100)
}
// Prints: 3, 3, 3 (expected 0, 1, 2)
// Investigation
// var is function-scoped, i is shared
// By time timeout fires, loop is done, i === 3
// Fix: Use let (block-scoped) or capture i## 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]console.log()console.table()console.trace()console.time()console.timeEnd()# Search for text in files
grep -r "error" logs/
# Follow log file
tail -f logs/app.log
# Search with context
grep -B 5 -A 5 "ERROR" logs/app.log
# Check disk space
df -h
# Check memory
free -m
# Check running processes
ps aux | grep node-- PostgreSQL
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
-- Show slow queries
SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;
-- Check table size
SELECT pg_size_pretty(pg_total_relation_size('users'));
-- Check indexes
\d usersBAD: "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."BAD: "The API must be returning valid data"
GOOD: "Let me log the API response to see what it actually returns"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."BAD: "Let me add console.log to production to see..."
GOOD: "Let me reproduce locally and debug there, or use proper logging"BAD: "It crashed once, let me guess why"
GOOD: "Let me find reliable way to reproduce it first"