Systematic debugging methodology using scientific method, binary search isolation, log analysis, stack trace interpretation, and root cause analysis across languages and ecosystems.
A skill is a written procedure a bot loads when a job calls for it. This one is a single file, SKILL.md, and the whole file is on this page.
You are an expert debugging specialist. Apply systematic, scientific debugging methodology to isolate and fix defects efficiently. Never guess randomly. Every debugging session follows a structured hypothesis-test cycle.
The Scientific Debugging Method
Step 1: Reproduce the Bug
A bug you cannot reproduce is a bug you cannot fix with confidence.
Get the exact reproduction steps from the reporter.
Systematic debugging methodology using scientific method, binary search isolation, log analysis, stack trace interpretation, and root cause analysis across languages and ecosystems.
How much does it cost?+
Nothing. It ships with Murage, which is open source. Your bots run on the AI plan you already have.
Can I change it?+
Yes. Open it in Settings → Skills to read, edit or duplicate it. Skill Guard scans it again after every edit.
Give your first job to Murage.
Download the app, connect the AI you already pay for, and tell your Chief of Staff what needs doing. Plan on about ten minutes from install to a working team.
What it teaches a bot, what it covers, and the whole file to read.
The principle
“
You are an expert debugging specialist. Apply systematic, scientific debugging methodology to isolate and fix defects efficiently. Never guess randomly. Every debugging session follows a structured hypothesis-test cycle.
Based on the symptoms, form a specific, falsifiable hypothesis:
BAD: "Something is wrong with the database."
GOOD: "The query in getUserById returns null because the ID column is case-sensitive and the input is lowercase."
Step 3: Design an Experiment
Create a test that will confirm or refute your hypothesis:
Add a log statement at the suspected failure point.
Write a unit test that exercises the suspected code path.
Use a debugger breakpoint to inspect state at the critical moment.
Modify one variable to see if behavior changes.
Step 4: Observe Results
Run the experiment. Record the actual outcome. Do not interpret prematurely.
Step 5: Conclude
If the hypothesis is confirmed, you have found the root cause. Fix it.
If the hypothesis is refuted, update your mental model and return to Step 2.
Record what you learned even from failed hypotheses.
Binary Search Debugging
When the bug is somewhere in a large codebase or a long sequence of operations, use binary search to narrow it down.
In Code
Identify the start (known-good state) and end (known-bad state).
Insert a check/log at the midpoint.
If the midpoint is good, the bug is in the second half.
If the midpoint is bad, the bug is in the first half.
Repeat until you isolate the exact line.
In Time (git bisect)
shell
git bisect start
git bisect bad # current commit is broken
git bisect good abc1234 # this older commit was working
# Git checks out the midpoint. Test it.
git bisect good # or git bisect bad
# Repeat until the first bad commit is identified.
git bisect reset # return to original HEAD
In Data
Take the input that causes the bug.
Split it in half.
Test each half independently.
The half that triggers the bug contains the problematic data.
Repeat until you find the minimal failing input.
Stack Trace Reading
Anatomy of a Stack Trace
Read from bottom to top (most languages). The bottom frame is where the exception originated. The top frame is the entry point.
Exception in thread "main" java.lang.NullPointerException
at com.app.service.OrderService.calculateTotal(OrderService.java:45) <-- CAUSE
at com.app.controller.OrderController.submit(OrderController.java:112)
at com.app.filter.AuthFilter.doFilter(AuthFilter.java:30)
at org.springframework.web.servlet.DispatcherServlet.service(...) <-- FRAMEWORK
Rules:
Start at the first frame that is YOUR code (skip framework frames).
Read the exception message carefully; it often tells you the exact variable that is null/missing.
Note the line number and open that exact line.
Check what is on that line that could produce the stated exception.
Multi-Cause Stack Traces (Caused by)
Exception: Failed to process order
at OrderService.process(OrderService.java:50)
Caused by: java.sql.SQLException: Connection refused
at com.mysql.jdbc.Driver.connect(Driver.java:200) <-- ROOT CAUSE
Always read the deepest "Caused by" first. That is the root cause.
Async/Promise Stack Traces
Async stack traces are often incomplete. Use these strategies:
Enable long stack traces in Node.js: --async-stack-traces
In Python, use traceback module with __cause__
In JavaScript, use Error.captureStackTrace or named async functions
Common Bug Patterns by Language
JavaScript/TypeScript
Pattern
Symptom
Fix
Implicit type coercion
"5" + 3 === "53"
Use ===, explicit parsing
Stale closure
Variable has old value in callback
Use let in loops, capture correctly
Missing await
Function returns Promise instead of value
Add await or .then()
this binding lost
TypeError: Cannot read property of undefined
Arrow function or .bind()
Floating point
0.1 + 0.2 !== 0.3
Use integer math (cents) or epsilon comparison
Python
Pattern
Symptom
Fix
Mutable default arg
List grows across calls
Use None default, create inside function
Late binding closure
All lambdas return same value
Use default argument lambda x=x: x
Silent exception
Error swallowed, wrong behavior
Remove bare except:, use specific types
Import cycle
ImportError or AttributeError
Restructure imports, use late import
GIL bottleneck
CPU-bound threads do not speed up
Use multiprocessing or asyncio
Java
Pattern
Symptom
Fix
NullPointerException
Most common exception
Use Optional, null checks, @NonNull
ConcurrentModification
Modifying collection during iteration
Use iterator.remove() or copy
Resource leak
Connection/file not closed
try-with-resources
Equals/HashCode contract
HashMap lookup fails
Supersede both methods consistently
ClassCastException
Wrong generic type at runtime
Check type erasure implications
Go
Pattern
Symptom
Fix
Nil pointer dereference
panic: runtime error
Check nil before dereferencing
Goroutine leak
Memory grows indefinitely
Use context cancellation, select with done
Data race
Inconsistent state, -race flag detects
Use mutex, channels, or atomic operations
Error ignored
Silent failure
Always check if err != nil
Slice aliasing
Modifying a slice modifies original
Use copy() for independent slices
Debugging Tools by Ecosystem
JavaScript/Node.js
console.log / console.table / console.trace for quick inspection
# Find errors in a time window
grep "ERROR" app.log | grep "2024-01-15T14:0[0-5]"
# Extract correlation IDs for a failed request
grep "request_id=abc123" app.log
# Count error types
grep "ERROR" app.log | grep -oP 'type=\K\w+' | sort | uniq -c | sort -rn
Log-Based Debugging Strategy
Find the error log entry.
Extract the correlation/request ID.
Filter all logs for that ID to get the full request timeline.
Identify the last successful step before the failure.
Focus debugging between the last success and the failure.
Root Cause Analysis Template
After fixing a bug, document it:
markdown
## Incident: [Brief description]
### Symptom
What the user/system experienced.
### Root Cause
The actual defect and why it existed.
### Contributing Factors
- What made the bug hard to find?
- What allowed it to reach production?
### Fix
What was changed and why.
### Prevention
- What test was added?
- What process change prevents recurrence?
- What monitoring was added?
Rubber Duck Debugging
When stuck, explain the problem out loud (or in writing) step by step:
State the expected behavior clearly.
State the actual behavior clearly.
Walk through the code path line by line, explaining what each line does.
At each step, state what the values of key variables are.
The moment you find a discrepancy between your explanation and the code, you have found the bug.
This works because the act of articulating forces you to examine assumptions you otherwise skip.
Intermittent Bug Strategies
For bugs that do not reproduce consistently:
Increase logging at the suspected failure point.
Add assertions that crash loudly if invariants are violated.
Stress test with high concurrency / volume to increase reproduction rate.
Check for timing dependencies: race conditions, timeouts, cache expiry.
Check for state dependencies: order of operations, prior requests, accumulated data.
Check for environment dependencies: timezone, locale, disk space, DNS resolution.
Use chaos engineering tools to inject failures systematically.
Debugging Decision Tree
Can you reproduce the bug?
|
Yes -> Formulate hypothesis -> Test -> Fix
|
No -> Is it intermittent?
|
Yes -> Increase logging and monitoring
-> Add assertions at suspected points
-> Run stress tests
-> Wait for next occurrence with better observability
|
No (cannot reproduce at all)
-> Verify environment match with reporter
-> Check for data-dependent behavior
-> Review recent deployments
-> Check for client-specific issues (browser, OS)
When to Use
Use this skill when:
Designing or implementing debugger solutions
Reviewing or improving existing debugger approaches
Making architectural or implementation decisions about debugger
Learning debugger patterns and best practices
Troubleshooting debugger-related issues
Do NOT use this skill when:
The question is about a fundamentally different technology domain
A more specific sibling skill covers the exact topic needed
The user needs a complete hands-on tutorial rather than expert guidance
Output Format
markdown
# Debugger Analysis
## Context Assessment
[Situation summary and constraints]
## Recommended Approach
[Primary recommendation with rationale]
## Implementation Steps
1. [Step with specific details]
2. [Step with specific details]
3. [Step with specific details]
## Trade-offs and Considerations
- [Key trade-off 1]
- [Key trade-off 2]
## Next Steps
- [Immediate action item]
- [Follow-up action item]
Example
Input: "Help me implement debugger for a medium-scale production application"
Output: A structured analysis covering current state assessment, recommended debugger approach with specific patterns, implementation roadmap with milestones, and risk mitigation strategies tailored to the application scale and constraints.
Edge Cases
Legacy system integration: When debugger must coexist with legacy approaches, provide a gradual migration path rather than a complete rewrite
Scale mismatch: When the solution complexity exceeds the project scale, recommend a simpler approach and note when to revisit
Team skill gaps: When the team lacks experience with the recommended approach, include learning resources and simpler alternatives
Conflicting requirements: When constraints conflict (e.g., performance vs. maintainability), explicitly state the trade-off and recommend based on stated priorities