Use when encountering bugs or test failures - systematic debugging using debuggers, internet research, and agents to find root cause before fixing
/plugin marketplace add withzombies/hyperpowers/plugin install withzombies-hyper@withzombies-hyperThis skill inherits all available tools. When active, it can use any tool Claude has access to.
resources/debugger-reference.mdresources/debugging-session-example.md<skill_overview> Random fixes waste time and create new bugs. Always use tools to understand root cause BEFORE attempting fixes. Symptom fixes are failure. </skill_overview>
<rigidity_level> MEDIUM FREEDOM - Must complete investigation phases (tools → hypothesis → test) before fixing.
Can adapt tool choice to language/context. Never skip investigation or guess at fixes. </rigidity_level>
<quick_reference>
| Phase | Tools to Use | Output |
|---|---|---|
| 1. Investigate | Error messages, internet-researcher agent, debugger, codebase-investigator | Root cause understanding |
| 2. Hypothesize | Form theory based on evidence (not guesses) | Testable hypothesis |
| 3. Test | Validate hypothesis with minimal change | Confirms or rejects theory |
| 4. Fix | Implement proper fix for root cause | Problem solved permanently |
FORBIDDEN: Skip investigation → guess at fix → hope it works REQUIRED: Tools → evidence → hypothesis → test → fix
Key agents:
internet-researcher - Search error messages, known bugs, solutionscodebase-investigator - Understand code structure, find related codetest-runner - Run tests without output pollution</quick_reference>
<when_to_use> Use for ANY technical issue:
ESPECIALLY when:
<the_process>
BEFORE attempting ANY fix, gather evidence with tools:
Dispatch internet-researcher with:
"Search for error: [exact error message]
- Check Stack Overflow solutions
- Look for GitHub issues in [library] version [X]
- Find official documentation explaining this error
- Check if this is a known bug"
What agent should find:
Claude cannot run debuggers directly. Instead:
Option A - Recommend debugger to user:
"Let's use lldb/gdb/DevTools to inspect state at error location.
Please run: [specific commands]
When breakpoint hits: [what to inspect]
Share output with me."
Option B - Add instrumentation Claude can add:
// Add logging
println!("DEBUG: var = {:?}, state = {:?}", var, state);
// Add assertions
assert!(condition, "Expected X but got {:?}", actual);
Dispatch codebase-investigator with:
"Error occurs in function X at line Y.
Find:
- How is X called? What are the callers?
- What does variable Z contain at this point?
- Are there similar functions that work correctly?
- What changed recently in this area?"
Based on evidence (not guesses):
Example:
Known: Error "null pointer" at auth.rs:45 when email is empty
Theory: Empty email bypasses validation, passes null to login()
Prediction: Adding validation before login() will prevent error
Test: Add validation, verify error doesn't occur with empty email
NEVER:
Minimal change to validate theory:
If confirmed: Proceed to Phase 4 If rejected: Return to Phase 1 with new information
After understanding root cause:
The fix should:
</the_process>
<examples> <example> <scenario>Developer encounters test failure, immediately tries "obvious" fix without investigation</scenario> <code> Test error: ``` FAIL: test_login_expired_token AssertionError: Expected Err(TokenExpired), got Ok(User) ```Developer thinks: "Obviously the token expiration check is wrong"
Makes change without investigation:
// "Fix" - just check if token is expired
if token.expires_at < now() {
return Err(AuthError::TokenExpired);
}
Commits without testing other cases. </code>
<why_it_fails> No investigation:
expires_at containsWhat actually happened: Token expires_at was being parsed incorrectly, always showing future date. The "fix" adds dead code that never runs.
Result: Bug not fixed, new dead code added, time wasted. </why_it_fails>
<correction> **Phase 1 - Investigate with tools:**# 1. Read complete error
FAIL: test_login_expired_token at line 45
Expected: Err(TokenExpired)
Got: Ok(User { id: 123 })
Token: { expires_at: "2099-01-01", ... }
Dispatch internet-researcher:
"Search for: token expiration always showing future date
- Check date parsing bugs
- Look for timezone issues
- Find JWT expiration handling"
Add instrumentation:
println!("DEBUG: expires_at = {:?}, now = {:?}, expired = {:?}",
token.expires_at, now(), token.expires_at < now());
Run test again:
DEBUG: expires_at = 2099-01-01T00:00:00Z, now = 2024-01-15T10:30:00Z, expired = false
Phase 2 - Hypothesis:
"Token expires_at is being set to 2099, not actual expiration. Problem is in token creation, not validation."
Phase 3 - Test: Check token creation code:
// Found the bug!
fn create_token() -> Token {
Token {
expires_at: "2099-01-01".parse()?, // HARDCODED!
...
}
}
Phase 4 - Fix root cause:
fn create_token(duration: Duration) -> Token {
Token {
expires_at: now() + duration, // Correct
...
}
}
Result: Root cause fixed, test passes, no dead code. </correction> </example>
<example> <scenario>Developer skips internet search, reinvents solution to known problem</scenario> <code> Error: ``` error: linking with `cc` failed: exit status: 1 ld: symbol(s) not found for architecture arm64 ```Developer thinks: "Must be a linking issue, I'll add flags"
Spends 2 hours trying different linker flags:
[target.aarch64-apple-darwin]
rustflags = ["-C", "link-arg=-undefined dynamic_lookup"]
# Doesn't work, tries more flags...
</code>
<why_it_fails> Skipped internet search:
Why it happens: Impatience, thinking "I can figure this out faster" </why_it_fails>
<correction> **Dispatch internet-researcher FIRST:**"Search for: 'symbol not found for architecture arm64' Rust linking
- Check Stack Overflow solutions
- Look for Xcode/macOS specific fixes
- Find Cargo configuration for Apple Silicon"
Agent returns (30 seconds):
Found on Stack Overflow (2.4k upvotes):
This occurs when Xcode Command Line Tools aren't installed or outdated.
Solution:
xcode-select --install
Or update existing:
softwareupdate --all --install --force
Apply solution:
xcode-select --install
# Wait for installation
cargo build
# Success!
Result: Fixed in 5 minutes, not 2 hours. </correction> </example>
<example> <scenario>Developer fixes symptom without understanding root cause, bug returns different way</scenario> <code> Bug: Users can delete other users' postsDeveloper notices: DELETE /posts/:id doesn't check ownership
"Fix":
@app.delete("/posts/{post_id}")
def delete_post(post_id: int, user: User):
post = get_post(post_id)
if post.author_id != user.id:
raise Forbidden()
delete(post)
Bug "fixed"... but bug report comes back: "Users can edit other users' posts" </code>
<why_it_fails> Symptom fix:
Root cause: No authorization middleware checking ownership across ALL endpoints.
Result: Whack-a-mole fixing symptoms, not the underlying issue. </why_it_fails>
<correction> **Phase 1 - Investigate with codebase-investigator:**"User can delete other users' posts. Investigate:
- What authorization exists across all post endpoints?
- Is there a pattern for ownership checks?
- Which other endpoints access posts?
- Is there middleware handling this?"
Agent reports:
Found:
- DELETE /posts/:id - NO ownership check
- PUT /posts/:id - NO ownership check
- GET /posts/:id - NO ownership check (allows viewing private posts!)
- No authorization middleware found
- Similar pattern in comments, likes endpoints
Phase 2 - Hypothesis: "Missing authorization layer. Need middleware checking resource ownership across ALL endpoints."
Phase 4 - Fix root cause:
# Add authorization middleware
class OwnershipMiddleware:
def check_ownership(self, resource, user):
if resource.author_id != user.id:
raise Forbidden()
# Apply to all endpoints
@app.delete("/posts/{post_id}")
@require_ownership(Post)
def delete_post(...):
...
@app.put("/posts/{post_id}")
@require_ownership(Post)
def update_post(...):
...
Result: Root cause fixed, ALL endpoints secured, not just one symptom. </correction> </example>
</examples><critical_rules>
Tools before fixes → Never guess without investigation
Evidence-based hypotheses → Not guesses or hunches
Test hypothesis before fixing → Minimal change to validate
Fix root cause, not symptom → One fix, many symptoms prevented
All of these mean: Stop, use tools to investigate:
</critical_rules>
<verification_checklist>
Before proposing any fix:
Before committing fix:
</verification_checklist>
<integration>This skill calls:
This skill is called by:
Agents used:
Detailed guides:
When stuck:
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.