Debugging Methodology
Reproduce, observe, hypothesize, isolate, verify. Resist guess-and-patch. Goal is root cause — fixing the wrong cause means it breaks again.
When to Use
- Test fails for non-obvious reason
- Behavior changed; cause unknown
- Bug is intermittent or environment-dependent
- User pattern-matches to a fix without root-cause evidence
- A fix was applied but the problem recurred or shifted
Core Methodology
Step 1: Reproduce the Failure
A bug you can't trigger is a bug you can't verify fixed.
- Record exact steps, inputs, environment
- For intermittent failures, characterize frequency and conditions (load, timing, data shape, concurrency)
- If it doesn't repro locally, identify the environmental delta (OS, deps, config, data volume, network)
- No reproduction, no diagnosis. If impossible, instrument code to capture state on next occurrence and proceed to Step 2 with available data
Step 2: Observe Before Theorizing
Premature hypotheses cause confirmation bias. Collect evidence first:
- Full error messages and stack traces (exact text, not paraphrased)
- Relevant log output around the failure
- System state: memory, CPU, disk, connections, queue depth
- Recent changes: commits, config, dependency updates, infra
- Data state: what input triggered it? Valid?
Separate facts ("NullPointerException on line 42") from interpretations ("the object must not be initialized").
Step 3: Generate and Rank Hypotheses
List every plausible cause. Rank by:
- Likelihood given evidence
- Testability — how fast to confirm/rule out
- Impact — severity if true
Prioritize likely + fast-to-test. A 30-second elimination check is always worth it.
Differential diagnosis — what changed?
- Code: recent commits, merges, refactors
- Configuration: env vars, feature flags, settings
- Data: new patterns, schema changes, edge cases
- Dependencies: version bumps, transitive changes
- Infrastructure: deployments, resource limits, network
Step 4: Isolate with Binary Search
Halve the search space; don't read line by line.
- Bisect commits:
git bisect
- Bisect code: stub components until failure disappears, re-enable one by one
- Bisect input: minimize failing input
- Bisect environment: swap one env variable at a time
Each step should halve the space. If not, change dimension.
Step 5: Confirm Root Cause and Fix
- Explain the mechanism — full causal chain from cause to symptom. Can't explain? It's proximate, not root.
- Predict — if this is the cause, what else should be true? Check.
- Fix at the root — not the symptom. A null check that suppresses a crash isn't a fix if the object should never be null.
- Verify — original repro resolved + run broader tests for regressions
- Write a regression test — encode the failure so it can't silently return
Feed root cause to five-whys-root-cause if systemic, or causal-inference if the claim needs rigorous validation.
Output Format
🔍 Symptom
- What fails: [exact error/behavior/test]
- When it fails: [always / intermittent / after action]
- Since when: [date/commit, or "unknown"]
📋 Observations
| Category |
Finding |
| Error message |
[exact text] |
| Logs |
[relevant lines] |
| Recent changes |
[commits, config, deps, infra] |
| Environment |
[OS, versions, resources] |
| Data |
[input, edge cases] |
🧠 Hypotheses
| # |
Hypothesis |
Likelihood |
Test |
Time |
| 1 |
[Most likely] |
High |
[check] |
[min] |
| 2 |
[Second] |
Medium |
[check] |
[min] |
| 3 |
[Third] |
Low |
[check] |
[min] |
🎯 Isolation
- Dimension: [commits / code / input / environment]
- Method: [git bisect / stubbing / input reduction / env swap]
- Result: [what was isolated]
🏆 Root Cause
- Cause: [precise]
- Mechanism: [full causal chain]
- Fix: [what to change]
- Verification: [how to confirm + regression test]
⚠️ Follow-Up
- Systemic?: [Yes → five-whys-root-cause / No]
- Causal claim?: [Yes → causal-inference / No]
- Other areas at risk: [shared pattern/assumption]
Common Traps
- Guess-and-patch: fix without confirmed root cause; symptom resurfaces or shifts
- Confirmation bias: only seeking supporting evidence; force yourself to disprove
- Fixing the symptom: null check / retry / try-catch suppressing without understanding
- Skipping reproduction: diving in before you can trigger; can't verify the fix
- Changing multiple things: bug gone, but you don't know which change fixed it
Thinking Triggers
- "Can I reproduce this on demand right now?"
- "What have I observed vs. what am I assuming?"
- "What changed between working and broken?"
- "What's the fastest test that eliminates my top hypothesis?"
- "Am I fixing the root cause or suppressing a symptom?"
1---2name: debugging-methodology3description: Apply debugging methodology whenever the user faces a software failure they cannot explain — a broken test, unexpected behavior, a regression, or an intermittent bug. Triggers on phrases like "why is this broken?", "how do I debug this?", "the test fails but I don't know why", "intermittent failure", "works on my machine", "this used to work", "regression". Use proactively when the user describes a symptom and jumps straight to a fix without isolating the root cause.4---56# Debugging Methodology78Reproduce, observe, hypothesize, isolate, verify. Resist guess-and-patch. Goal is root cause — fixing the wrong cause means it breaks again.910---1112## When to Use1314- Test fails for non-obvious reason15- Behavior changed; cause unknown16- Bug is intermittent or environment-dependent17- User pattern-matches to a fix without root-cause evidence18- A fix was applied but the problem recurred or shifted1920---2122## Core Methodology2324### Step 1: Reproduce the Failure2526A bug you can't trigger is a bug you can't verify fixed.2728- Record exact steps, inputs, environment29- For intermittent failures, characterize frequency and conditions (load, timing, data shape, concurrency)30- If it doesn't repro locally, identify the environmental delta (OS, deps, config, data volume, network)31- **No reproduction, no diagnosis.** If impossible, instrument code to capture state on next occurrence and proceed to Step 2 with available data3233### Step 2: Observe Before Theorizing3435Premature hypotheses cause confirmation bias. Collect evidence first:3637- Full error messages and stack traces (exact text, not paraphrased)38- Relevant log output around the failure39- System state: memory, CPU, disk, connections, queue depth40- Recent changes: commits, config, dependency updates, infra41- Data state: what input triggered it? Valid?4243Separate facts ("NullPointerException on line 42") from interpretations ("the object must not be initialized").4445### Step 3: Generate and Rank Hypotheses4647List every plausible cause. Rank by:48491. **Likelihood** given evidence502. **Testability** — how fast to confirm/rule out513. **Impact** — severity if true5253Prioritize likely + fast-to-test. A 30-second elimination check is always worth it.5455**Differential diagnosis — what changed?**56- **Code**: recent commits, merges, refactors57- **Configuration**: env vars, feature flags, settings58- **Data**: new patterns, schema changes, edge cases59- **Dependencies**: version bumps, transitive changes60- **Infrastructure**: deployments, resource limits, network6162### Step 4: Isolate with Binary Search6364Halve the search space; don't read line by line.6566- **Bisect commits**: `git bisect`67- **Bisect code**: stub components until failure disappears, re-enable one by one68- **Bisect input**: minimize failing input69- **Bisect environment**: swap one env variable at a time7071Each step should halve the space. If not, change dimension.7273### Step 5: Confirm Root Cause and Fix74751. **Explain the mechanism** — full causal chain from cause to symptom. Can't explain? It's proximate, not root.762. **Predict** — if this is the cause, what else should be true? Check.773. **Fix at the root** — not the symptom. A null check that suppresses a crash isn't a fix if the object should never be null.784. **Verify** — original repro resolved + run broader tests for regressions795. **Write a regression test** — encode the failure so it can't silently return8081Feed root cause to `five-whys-root-cause` if systemic, or `causal-inference` if the claim needs rigorous validation.8283---8485## Output Format8687### 🔍 Symptom88- **What fails**: [exact error/behavior/test]89- **When it fails**: [always / intermittent / after action]90- **Since when**: [date/commit, or "unknown"]9192### 📋 Observations93| Category | Finding |94|----------|---------|95| Error message | [exact text] |96| Logs | [relevant lines] |97| Recent changes | [commits, config, deps, infra] |98| Environment | [OS, versions, resources] |99| Data | [input, edge cases] |100101### 🧠 Hypotheses102| # | Hypothesis | Likelihood | Test | Time |103|---|-----------|------------|------|------|104| 1 | [Most likely] | High | [check] | [min] |105| 2 | [Second] | Medium | [check] | [min] |106| 3 | [Third] | Low | [check] | [min] |107108### 🎯 Isolation109- **Dimension**: [commits / code / input / environment]110- **Method**: [git bisect / stubbing / input reduction / env swap]111- **Result**: [what was isolated]112113### 🏆 Root Cause114- **Cause**: [precise]115- **Mechanism**: [full causal chain]116- **Fix**: [what to change]117- **Verification**: [how to confirm + regression test]118119### ⚠️ Follow-Up120- **Systemic?**: [Yes → five-whys-root-cause / No]121- **Causal claim?**: [Yes → causal-inference / No]122- **Other areas at risk**: [shared pattern/assumption]123124---125126## Common Traps127128- **Guess-and-patch**: fix without confirmed root cause; symptom resurfaces or shifts129- **Confirmation bias**: only seeking supporting evidence; force yourself to *disprove*130- **Fixing the symptom**: null check / retry / try-catch suppressing without understanding131- **Skipping reproduction**: diving in before you can trigger; can't verify the fix132- **Changing multiple things**: bug gone, but you don't know which change fixed it133134---135136## Thinking Triggers137138- *"Can I reproduce this on demand right now?"*139- *"What have I observed vs. what am I assuming?"*140- *"What changed between working and broken?"*141- *"What's the fastest test that eliminates my top hypothesis?"*142- *"Am I fixing the root cause or suppressing a symptom?"*