Debug Runtime
Root-cause fast: evidence → origin → hypothesis → confirm → fix or escalate.
Workflow
1. Evidence
Stack trace/error (file:line), what happened, environment, recent changes. If unavailable, tail the logs:
tail -100 logs/app.log | grep -i "error\|fatal\|exception"
journalctl -u <service> -n 100 --no-pager
docker logs <container> --tail 100
2. Origin
Deepest frame in YOUR code (skip framework frames — Express/Rails/Django/Next.js). Read it and its caller. Sparse? grep -rn "error text" src/
3. Hypothesis
"This occurs because [condition] when [state is X]." Check error type, call path, recent changes.
4. Confirm
| Method | When to use |
|---|---|
| Targeted failing test | Root cause clear, want a regression guard |
| One-line debug log + re-run | Need to observe live state |
| Call function in REPL/scratch file | Input known, fastest to isolate |
5. Fix or escalate
Fix inline when ≤10 lines, root cause unambiguous. Escalate to /triage-issue when:
- fix needs a design decision or touches multiple callers
- it's a symptom of a deeper structural problem
- you want a tracked issue + TDD plan before changing code
Edge cases
| Situation | Action |
|---|---|
| No stack trace | Verbose logging/DEBUG=*; check error page |
| Prod-only | Diff env/config across envs; read config-loading code |
| Race condition | Shared mutable state, missing locks, non-atomic ops |
| External dependency | Read library source; check its GitHub issues |
| Minified trace | Ask for source map; rebuild with NODE_ENV=development |
| No repro | Ask for a verbose-logged repro; check load/input correlation |