
Debugging Wizard
Give your agent a repeatable bug-hunting playbook—from race conditions and null refs to memory leaks and stale React state.
Overview
Debugging Wizard is a journey-wide agent skill that maps common bug symptoms to fixes—usable whenever a solo builder needs systematic diagnosis before committing patches.
Install
npx skills add https://github.com/jeffallan/claude-skills --skill debugging-wizardWhat is this skill?
- Symptom-to-cause pattern table covering eight common bug classes
- Fix recipes for race conditions, off-by-one, and null reference crashes
- Memory leak guidance for uncleaned listeners and intervals
- Stale React state and closure-in-loop explanations with code fixes
- Language-agnostic TypeScript-oriented examples usable across stacks
- 8-row common bug pattern recognition table
Adoption & trust: 2.8k installs on skills.sh; 9.7k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You keep hitting the same classes of bugs—races, nulls, leaks, stale state—but your agent guesses fixes instead of matching patterns.
Who is it for?
Builders who want fast pattern-matching debug help in TypeScript/JavaScript-heavy apps during any phase of the journey.
Skip if: Deep performance profiling, security penetration testing, or hardware/kernel debugging where this checklist does not apply.
When should I use this skill?
Intermittent failures, crash logs, memory growth, or confusing JS/TS behavior during agent-assisted debugging.
What do I get? / Deliverables
The agent proposes evidence-backed fixes aligned to recognized bug patterns, shrinking debug loops across features and incidents.
- Root-cause hypothesis tied to a named pattern
- Concrete patch suggestions with before/after snippets
Recommended Skills
Journey fit
Useful at every journey phase - explore requirements and options before committing to a direction.
Where it fits
Stale React state after rapid clicks—apply closure and state-update guidance before merging the feature.
N+1 query slowness appears in a new API—recognize the loop-fetch pattern and batch loads.
Flaky CI from race conditions—enforce await on async setup before release candidate.
Production spikes on null reference crashes—optional chaining and guard clauses in hot paths.
Support tickets describe intermittent failures—map symptoms to race or leak patterns for a targeted hotfix.
How it compares
Use as a structured bug-pattern reference instead of unstructured “try random changes” chat debugging.
Common Questions / FAQ
Who is debugging-wizard for?
Solo and indie developers who want agents to diagnose familiar JavaScript/TypeScript defect patterns with concrete fix snippets.
When should I use debugging-wizard?
During Build when tests fail mysteriously, during Ship when stabilizing flaky CI, during Operate when user-reported errors spike, or anytime intermittent bugs appear.
Is debugging-wizard safe to install?
It contains no executable hooks by itself; confirm repo trust via the Security Audits panel on this Prism page before installation.
SKILL.md
READMESKILL.md - Debugging Wizard
# Common Bug Patterns ## Pattern Recognition | Pattern | Symptom | Likely Cause | |---------|---------|--------------| | Race condition | Intermittent failures | Missing await, async timing | | Off-by-one | Missing first/last item | `<` vs `<=`, array bounds | | Null reference | "undefined is not..." | Missing null check | | Memory leak | Growing memory | Uncleaned listeners/intervals | | N+1 queries | Slow with more data | Fetching in loop | | Type coercion | Unexpected behavior | `==` instead of `===` | | Closure issue | Wrong variable value | Loop variable capture | | Stale state | Old value used | React state closure | ## Race Condition ```typescript // BUG: Race condition let data; fetchData().then(result => { data = result; }); console.log(data); // undefined! // FIX: Await the result const data = await fetchData(); console.log(data); ``` ## Off-by-One ```typescript // BUG: Skips last element for (let i = 0; i < array.length - 1; i++) { } // FIX: Include last element for (let i = 0; i < array.length; i++) { } // BUG: Array index out of bounds const last = array[array.length]; // undefined // FIX: Correct index const last = array[array.length - 1]; ``` ## Null Reference ```typescript // BUG: Crashes if user is null const name = user.profile.name; // FIX: Optional chaining const name = user?.profile?.name ?? 'Unknown'; // FIX: Guard clause if (!user?.profile) { return 'Unknown'; } return user.profile.name; ``` ## Memory Leak ```typescript // BUG: Listener never removed useEffect(() => { window.addEventListener('resize', handleResize); }, []); // FIX: Cleanup function useEffect(() => { window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // BUG: Interval never cleared setInterval(pollData, 1000); // FIX: Store and clear const intervalId = setInterval(pollData, 1000); return () => clearInterval(intervalId); ``` ## Closure in Loop ```typescript // BUG: All callbacks use i = 5 for (var i = 0; i < 5; i++) { setTimeout(() => console.log(i), 100); } // FIX: Use let (block scoped) for (let i = 0; i < 5; i++) { setTimeout(() => console.log(i), 100); } // FIX: Capture in closure for (var i = 0; i < 5; i++) { ((j) => setTimeout(() => console.log(j), 100))(i); } ``` ## React Stale State ```typescript // BUG: count is stale in closure const [count, setCount] = useState(0); useEffect(() => { setInterval(() => { setCount(count + 1); // Always uses initial count }, 1000); }, []); // FIX: Use functional update setCount(prev => prev + 1); // FIX: Include in dependency array with cleanup useEffect(() => { const id = setInterval(() => setCount(c => c + 1), 1000); return () => clearInterval(id); }, []); ``` ## Quick Reference | Symptom | First Check | |---------|-------------| | "undefined is not..." | Null check missing | | Works sometimes | Race condition | | Wrong value in callback | Closure/stale state | | Gets slower over time | Memory leak, N+1 | | Off by one item | Loop bounds, array index | | Type mismatch | `==` vs `===`, coercion | # Debugging Tools ## Debuggers by Language | Language | Debugger | Start Command | |----------|----------|---------------| | TypeScript/JS | Node Inspector | `node --inspect` | | Python | pdb/ipdb | `python -m pdb` | | Go | Delve | `dlv debug` | | Rust | rust-gdb/lldb | `rust-gdb ./target/debug/app` | | Java | JDB/IDE | IDE debugger | ## Node.js / TypeScript ```bash # Start with inspector node --inspect dist/main.js # Break on first line node --inspect-brk dist/main.js # With ts-node node --inspect -r ts-node/register src/main.ts ``` ```typescript // In code debugger; // Breakpoint // Quick print console.log({ variable }); // Shows name and value console.table(arrayOfObjects); // Table format console.trace('Called from'); // Stack trace ``` ## Python ```bash # Start debugger python -m pdb script.py # Post-mortem on exception python -m pdb -c continue script.py ``` ```pyt