Systematic Debugging
4-phase root cause debugging process. Gather evidence, form hypotheses, test hypotheses, confirm root cause. Use for any bug diagnosis within the Bayes Ship pipeline. Includes defense-in-depth and condition-based-waiting techniques.
Systematic Debugging
Process over guessing
Never guess at fixes. Follow the 4-phase process:
Phase 1: Gather evidence
- Read error messages, stack traces, and logs CAREFULLY
- Identify the exact line and condition where failure occurs
- Note what DOES work (narrowing the search space is as valuable as finding the bug)
Phase 2: Form hypotheses
- List 2-3 possible causes based on evidence
- Rank by likelihood
- Each hypothesis must be testable
Phase 3: Test hypotheses
- Add targeted logging or breakpoints
- Inspect state at the point of failure
- Trace execution path
- Eliminate hypotheses one by one
Phase 4: Confirm root cause
- The fix must address the ACTUAL cause, not a symptom
- Ask: "If I revert this fix, does the bug come back?" (mentally or actually)
- Ask: "Does this fix handle the general case, or just the specific trigger I found?"
Defence-in-depth
After fixing the immediate bug, consider:
- Should there be a defensive check upstream that catches this class of error earlier?
- Should there be a test that prevents regression?
- Is this a symptom of a broader design issue?
Condition-based waiting
When debugging async or timing-dependent issues:
- Never use
sleep()as a fix. It masks the problem. - Wait for CONDITIONS, not TIME. Poll for the expected state.
- If a race condition exists, the fix is synchronization, not delays.