systematic-debugging · v1.0.0 · 2026-05-03 · sha256 53acdb9c0cd5b524
systematic-debugging v1.0.0A
Immutable. This exact content is served forever at /api/v1/blob/53acdb9c0cd5b524.
---
name: systematic-debugging
description: Four-phase root cause investigation process for diagnosing bugs, errors, and unexpected behavior
category: developer
version: 1.0.0
origin: aiden
license: Apache-2.0
tags: debugging, root-cause, investigation, bug, error, diagnosis, troubleshooting, logs, testing
---
# Systematic Debugging
A structured four-phase process for diagnosing software bugs: **Reproduce → Isolate → Hypothesize → Verify**. Prevents guessing and ensures you find the root cause, not just a workaround.
## When to Use
- User reports a bug or unexpected behavior without an obvious cause
- An error message appears but the source is unclear
- A fix was applied but the problem persists
- Tests are failing intermittently (flaky tests)
- Production behavior differs from local behavior
## How to Use
### Phase 1: Reproduce reliably
A bug you can reproduce consistently is halfway solved.
```
1. Get the exact error message, stack trace, and environment
2. Identify exact steps to trigger the bug
3. Confirm the bug happens in a clean environment (not just local state)
4. Record: OS, runtime version, dependencies, config values
5. Try: does it fail on every run, or only sometimes?
```
If intermittent: add timing, logging, or retry logic to isolate the trigger.
### Phase 2: Isolate the failure
Narrow the failure to the smallest possible unit.
```
1. Add logging before/after suspected areas to find where state diverges
2. Binary search through code: comment out half, does it still fail?
3. Check: when did this last work? (git log, git bisect)
4. Check: what changed recently? (git diff main, dependency updates)
5. Reproduce in a minimal test case — strip away all unrelated code
```
```powershell
# git bisect to find the breaking commit
git bisect start
git bisect bad # current commit is broken
git bisect good v2.0.0 # last known good tag
# git will checkout commits — test each, then:
git bisect good # or
git bisect bad
# Repeat until git identifies the culprit commit
git bisect reset
```
### Phase 3: Generate hypotheses
Form 2-3 specific, testable hypotheses about the root cause.
```
Bad hypothesis: "Something is wrong with the database"
Good hypothesis: "The connection pool is exhausted under concurrent load
because maxConnections defaults to 5 in test config"
For each hypothesis:
- What evidence supports it?
- What evidence would refute it?
- What one-line change would test it?
```
Rank by probability and test from most to least likely.
### Phase 4: Verify and fix
Prove the fix, not just that the error goes away.
```
1. Apply the smallest change that addresses the root cause
2. Run the original reproduction steps — confirm bug is gone
3. Run the full test suite — confirm no regressions
4. Check edge cases: empty input, null values, concurrent access
5. Write a regression test that would have caught this bug
```
```python
# Regression test template
def test_issue_42_connection_pool_exhaustion():
"""
Regression test: ensure concurrent requests don't exhaust the connection pool.
Root cause: maxConnections was not configurable; defaulted to 5 in test.
Fixed in commit abc123.
"""
results = run_concurrent_requests(count=20)
assert all(r.status_code == 200 for r in results), "Some requests failed under concurrency"
```
### Debugging cheat sheet
```
Error: KeyError / undefined → check input shapes; add null guard
Error: Off-by-one → examine loop bounds and index math
Error: Works locally, fails in CI → check env vars, file paths, timing
Error: Works first run, fails after → check state mutation, cache, side effects
Error: Inconsistent / race condition → check shared mutable state, locks
Error: Memory leak → profile allocations; check event listener cleanup
```
## Examples
**"My API returns 500 randomly but I can't reproduce it"**
→ Start at Phase 1 — add structured logging with request IDs. Once patterns emerge, apply Phase 2 binary search.
**"Tests pass locally but fail in GitHub Actions"**
→ Phase 2: diff the environments (OS, Node version, env vars). Often caused by missing env vars or OS path differences.
**"I fixed the bug but it came back after a week"**
→ Phase 4: add a regression test and check if the root cause fix addressed the underlying issue or just a symptom.
## Cautions
- Never apply multiple changes at once when debugging — you won't know which one fixed it
- "Works on my machine" is a Phase 1 failure — always reproduce in the target environment
- Logs and print statements are powerful — do not underestimate them in favor of complex tooling
- Document the root cause in the fix commit message so future developers understand why the change was made