| name | debug-issues |
| description | Debug bugs and errors using intel-first approach with systematic root cause analysis. Use proactively when errors occur, tests fail, or unexpected behavior appears. MUST trace from symptom to root cause with CoD^Σ reasoning. |
Debugging Skill
Overview
This skill performs systematic bug diagnosis using intelligence-first approach to trace from symptom to root cause with complete CoD^Σ reasoning chain.
Core principle: Capture symptom → Parse error → Intel trace → Root cause → Propose fix
Announce at start: "I'm using the debug-issues skill to diagnose this problem."
Quick Reference
| Phase | Key Activities | Output |
|---|---|---|
| 1. Capture Symptom | Reproduction steps, error message, environment | Symptom description |
| 2. Parse Error | Extract error type, file:line, stack trace | Parsed error object |
| 3. Intel Trace | project-intel.mjs queries from error to cause | Intel evidence chain |
| 4. Root Cause | Identify specific file:line with CoD^Σ trace | Root cause |
| 5. Report | Generate bug report with fix proposal | bug-report.md |
Templates You Will Use
- @.claude/templates/bug-report.md - Complete bug report with fix (Phase 5)
- @.claude/templates/mcp-query.md - For verifying library behavior (Phase 4)
Intelligence Tool Guide
- @.claude/shared-imports/project-intel-mjs-guide.md - For systematic intel queries
The Process
Copy this checklist to track progress:
Debugging Progress:
- [ ] Phase 1: Symptom Captured (reproduction steps documented)
- [ ] Phase 2: Error Parsed (file:line extracted)
- [ ] Phase 3: Intel Trace Complete (queries executed)
- [ ] Phase 4: Root Cause Identified (specific file:line)
- [ ] Phase 5: Bug Report Generated (with fix proposal)
Phase 1: Capture Symptom
Document the complete symptom:
Error Message:
TypeError: Cannot read property 'discount' of undefined at calculateTotal (src/pricing/calculator.ts:67) at processCheckout (src/checkout/checkout.ts:123)Reproduction Steps:
1. Add items to cart 2. Apply discount code "SAVE20" 3. Click "Checkout" 4. ERROR: 500 responseFrequency & Environment:
- Frequency: 15% of checkout attempts - Environment: Production - User impact: High (blocks checkout)
Enforcement:
- Complete error message captured
- Reproduction steps documented
- Frequency and environment noted
Phase 2: Parse Error
Extract structured information from error:
Parse Stack Trace
ERROR: TypeError: Cannot read property 'discount' of undefined
at calculateTotal (src/pricing/calculator.ts:67) ← ROOT ERROR
at processCheckout (src/checkout/checkout.ts:123)
at POST /api/checkout (src/api/routes.ts:45)
Parsed:
{
error_type: "TypeError",
message: "Cannot read property 'discount' of undefined",
root_location: "src/pricing/calculator.ts:67",
root_function: "calculateTotal",
call_chain: [
"src/api/routes.ts:45",
"src/checkout/checkout.ts:123",
"src/pricing/calculator.ts:67"
]
}
Identify Entry Point
Entry point: src/pricing/calculator.ts:67
Function: calculateTotal
Issue: Accessing .discount on undefined object
Enforcement:
- Error type identified
- Root file:line extracted
- Function name identified
- Call chain documented
Phase 3: Intel Trace
Use project-intel.mjs to trace from error to cause.
Query 1: Locate Function
project-intel.mjs --search "calculateTotal" --type ts --json > /tmp/debug_search.json
Result:
{
"files": [
"src/pricing/calculator.ts",
"src/pricing/calculator.test.ts"
]
}
Query 2: Analyze Symbols
project-intel.mjs --symbols src/pricing/calculator.ts --json > /tmp/debug_symbols.json
Result:
{
"symbols": [
{"name": "calculateTotal", "line": 62, "type": "function"},
{"name": "applyDiscount", "line": 89, "type": "function"},
{"name": "getDiscount", "line": 105, "type": "function"}
]
}
Key Finding: calculateTotal is at line 62, error at line 67 (5 lines into function)
Query 3: Trace Dependencies
# What does calculateTotal import?
project-intel.mjs --dependencies src/pricing/calculator.ts --direction upstream --json
Result:
{
"imports": [
{"module": "./discountService", "symbols": ["getDiscount"]},
{"module": "../models/Cart", "symbols": ["Cart"]},
{"module": "../utils/currency", "symbols": ["formatPrice"]}
]
}
Key Finding: Imports getDiscount from discountService - likely source of undefined
Query 4: Check getDiscount Function
project-intel.mjs --symbols src/pricing/discountService.ts --json
Result:
{
"symbols": [
{"name": "getDiscount", "line": 12, "type": "function", "returns": "Discount | undefined"}
]
}
CRITICAL FINDING: getDiscount returns Discount | undefined - can be undefined!
Enforcement:
- All relevant files identified
- Symbol locations found
- Dependencies traced
- Return types checked
Phase 4: Identify Root Cause
Now read ONLY the relevant lines identified by intel:
Targeted Read 1: Error Location
sed -n '62,75p' src/pricing/calculator.ts
Code:
// Line 62
export function calculateTotal(cart: Cart, discountCode?: string): number {
const subtotal = cart.items.reduce((sum, item) => sum + item.price * item.quantity, 0)
// Line 67 - ERROR LINE
const discountAmount = discountCode
? getDiscount(discountCode).discount * subtotal // ← BUG: no null check
: 0
const total = subtotal - discountAmount
return formatPrice(total)
}
Targeted Read 2: getDiscount Function
sed -n '12,25p' src/pricing/discountService.ts
Code:
// Line 12
export function getDiscount(code: string): Discount | undefined {
const discount = discounts.find(d => d.code === code && d.active)
return discount // ← Returns undefined when code not found
}
Root Cause Analysis (CoD^Σ)
**Claim:** Error occurs because calculateTotal doesn't handle undefined from getDiscount
**Complete CoD^Σ Trace:**
Step 1: → ParseError ↳ Source: Error log ↳ Data: TypeError at src/pricing/calculator.ts:67
Step 2: ⇄ IntelQuery("locate calculateTotal") ↳ Query: project-intel.mjs --search "calculateTotal" ↳ Data: Found in src/pricing/calculator.ts at line 62
Step 3: ⇄ IntelQuery("analyze symbols") ↳ Query: project-intel.mjs --symbols calculator.ts ↳ Data: calculateTotal at line 62, error at line 67 (5 lines in)
Step 4: → TargetedRead(lines 62-75) ↳ Source: sed -n '62,75p' calculator.ts ↳ Data: Line 67 calls getDiscount(code).discount without null check
Step 5: ⇄ IntelQuery("check getDiscount") ↳ Query: project-intel.mjs --symbols discountService.ts ↳ Data: getDiscount returns Discount | undefined
Step 6: → TargetedRead(getDiscount function) ↳ Source: sed -n '12,25p' discountService.ts ↳ Data: Returns undefined when code not found/inactive
Step 7: ⊕ MCPVerify("TypeScript best practices") ↳ Tool: Ref MCP ↳ Query: "TypeScript optional chaining undefined handling" ↳ Data: Use ?. operator for potentially undefined values
Step 8: ∘ Conclusion ↳ Logic: getDiscount returns undefined → accessing .discount throws TypeError ↳ Root Cause: src/pricing/calculator.ts:67 - missing null check ↳ Fix: Use optional chaining: getDiscount(code)?.discount ?? 0
Token Comparison:
- Reading full files: ~8600 tokens
- Intel + targeted reads: ~750 tokens
- Savings: 91%
Enforcement:
- Root cause identified with specific file:line
- Complete CoD^Σ trace documented
- MCP verification performed
- Fix approach validated
Phase 5: Generate Bug Report
Use @.claude/templates/bug-report.md to create comprehensive report:
---
bug_id: "checkout-discount-500"
severity: "critical"
status: "open"
assigned_to: "executor-agent"
---
# Bug Report: 500 Error on Checkout with Discount
## Symptom
[Full symptom from Phase 1]
## CoD^Σ Trace
[Complete trace from Phase 4]
## Root Cause
**Location:** src/pricing/calculator.ts:67
**Issue:** Missing null check before accessing .discount property
**Why It Fails:**
- getDiscount() returns Discount | undefined
- When discount code invalid/inactive, returns undefined
- Code attempts undefined.discount → TypeError
## Fix Specification
**Approach:** Add optional chaining
**Changes Required:**
```typescript
// Before (buggy)
const discountAmount = discountCode
? getDiscount(discountCode).discount * subtotal
: 0
// After (fixed)
const discountAmount = discountCode
? (getDiscount(discountCode)?.discount ?? 0) * subtotal
: 0
Reason:
- Optional chaining (?.) returns undefined if getDiscount returns undefined
- Nullish coalescing (?? 0) provides default value
- No TypeError, discount defaults to 0 for invalid codes
Verification
Test Plan:
it('handles invalid discount codes gracefully', () => {
const cart = { items: [{ price: 100, quantity: 1 }] }
const total = calculateTotal(cart, 'INVALID_CODE')
expect(total).toBe(100) // No discount applied, no error
})
Acceptance Criteria:
- Invalid discount codes return subtotal (no discount)
- Valid discount codes still apply correctly
- No TypeError thrown
**File Naming:** `YYYYMMDD-HHMM-bug-<id>.md`
**Enforcement:**
- [ ] Bug report uses template
- [ ] CoD^Σ trace complete
- [ ] Root cause with file:line specified
- [ ] Fix proposal provided
- [ ] Verification plan included
## Common Error Patterns
### Pattern 1: React Infinite Re-render
**Symptom:**
Warning: Maximum update depth exceeded Component: LoginForm
**Debugging Process:**
- Search for component: project-intel.mjs --search "LoginForm" --type tsx
- Analyze symbols: Find useEffect hooks
- Targeted read: Check dependency arrays
- Common cause: useEffect depends on value it mutates
- MCP verify: Ref MCP "React useEffect dependencies"
- Fix: Remove mutated value from dependencies or use functional setState
### Pattern 2: N+1 Query Problem
**Symptom:**
Slow page load (10+ seconds) Dashboard with 100 users
**Debugging Process:**
- Search for data fetch: project-intel.mjs --search "fetchUsers"
- Analyze code: Look for loops around database queries
- Common pattern: users.forEach(user => { const posts = await db.query("SELECT * FROM posts WHERE user_id = ?", user.id) }) // ← Query inside loop!
- Fix: Single query with JOIN or WHERE IN clause
### Pattern 3: Memory Leak
**Symptom:**
Browser tab memory grows over time Eventually crashes
**Debugging Process:**
- Search for event listeners: project-intel.mjs --search "addEventListener"
- Check useEffect cleanup: Look for return functions
- Common issue: Missing cleanup
- MCP verify: Ref MCP "React useEffect cleanup"
- Fix: Add cleanup function: useEffect(() => { window.addEventListener('resize', handler) return () => window.removeEventListener('resize', handler) // ← Cleanup }, [])
## Enforcement Rules
### Rule 1: Complete CoD^Σ Trace
**❌ Violation:**
The bug is in the discount calculation.
**✓ Correct:**
Root cause: src/pricing/calculator.ts:67
CoD^Σ Trace: Step 1: ParseError → TypeError at line 67 Step 2: IntelQuery → getDiscount returns undefined Step 3: MCPVerify → TypeScript docs confirm optional chaining needed Step 4: Conclusion → Missing null check causes error
### Rule 2: Intel Before Reading
**❌ Violation:**
```bash
# Read entire codebase looking for bug
cat src/**/*.ts # Thousands of lines
✓ Correct:
# Intel-first approach
project-intel.mjs --search "calculateTotal" # Find exact file
project-intel.mjs --symbols calculator.ts # Find exact line
sed -n '62,75p' calculator.ts # Read only relevant lines
Rule 3: Propose Fix with Verification
❌ Violation:
Fix: Change the code to handle undefined.
✓ Correct:
Fix: Use optional chaining at line 67:
getDiscount(code)?.discount ?? 0
Verification:
- Test with invalid code (should return subtotal)
- Test with valid code (should apply discount)
- AC: No errors thrown for any input
Common Pitfalls
| Pitfall | Impact | Solution |
|---|---|---|
| Assumptions without verification | Wrong diagnosis | Use MCP to verify library behavior |
| Skipping intel queries | Token waste | Always query before reading |
| Incomplete reproduction steps | Can't verify fix | Document exact steps |
| No fix proposal | Bug remains open | Always propose specific fix |
When to Use This Skill
Use debug-issues when:
- User reports an error or bug
- Tests are failing
- Unexpected behavior occurs
- Performance is degraded
- Memory issues detected
Don't use when:
- User wants general code analysis (use analyze-code skill)
- User wants to plan implementation (use create-plan skill)
- No specific error (use analyze-code for investigation)
Related Skills & Commands
- Analyze-code skill - For general code analysis (not bug-specific)
- Implement-and-verify skill - For implementing the fix after debugging
- /bug command - User-invoked debugging (can invoke this skill)
Success Metrics
Accuracy:
- Root cause identified: 95%+
- Fix proposal validated: 100%
Efficiency:
- Token usage: 80%+ savings vs direct reading
- Time to diagnosis: 5-15 minutes
Completeness:
- CoD^Σ trace: 100% complete
- MCP verification: 100% for library issues
Version
Version: 1.0 Last Updated: 2025-10-19 Owner: Claude Code Intelligence Toolkit