Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Systematically finds and fixes bugs using proven debugging techniques. Traces from symptoms to root cause, implements fixes, and prevents regression.
.claude/skills/bug-hunter/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-22 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✓ | ▲ Improved | — | — |
| case-03 | ✗→✗ | = Same ✗ | — | — |
| case-08 | ✗→✗ | = Same ✗ | — | — |
| case-02 | ✗→✗ | = Same ✗ | — | — |
Systematically hunt down and fix bugs using proven debugging techniques. No guessing—follow the evidence.
First, make it happen consistently:
1. Get exact steps to reproduce
2. Try to reproduce locally
3. Note what triggers it
4. Document the error message/behavior
5. Check if it happens every time or randomlyIf you can't reproduce it, gather more info:
Collect all available information:
Check logs:
bash# Application logs tail -f logs/app.log # System logs journalctl -u myapp -f # Browser console # Open DevTools → Console tab
Check error messages:
Check state:
Based on evidence, guess what's wrong:
"The login times out because the session cookie
expires before the auth check completes"
"The form fails because email validation regex
doesn't handle plus signs"
"The API returns 500 because the database query
has a syntax error with special characters"Prove or disprove your guess:
Add logging:
javascriptconsole.log('Before API call:', userData); const response = await api.login(userData); console.log('After API call:', response);
Use debugger:
javascriptdebugger; // Execution pauses here const result = processData(input);
Isolate the problem:
javascript// Comment out code to narrow down // const result = complexFunction(); const result = { mock: 'data' }; // Use mock data
Trace back to the actual problem:
Common root causes:
Example trace:
Symptom: "Cannot read property 'name' of undefined"
↓
Where: user.profile.name
↓
Why: user.profile is undefined
↓
Why: API didn't return profile
↓
Why: User ID was null
↓
Root cause: Login didn't set user ID in sessionFix the root cause, not the symptom:
Bad fix (symptom):
javascript// Just hide the error const name = user?.profile?.name || 'Unknown';
Good fix (root cause):
javascript// Ensure user ID is set on login const login = async (credentials) => { const user = await authenticate(credentials); if (user) { session.userId = user.id; // Fix: Set user ID return user; } throw new Error('Invalid credentials'); };
Verify it actually works:
1. Reproduce the original bug
2. Apply the fix
3. Try to reproduce again (should fail)
4. Test edge cases
5. Test related functionality
6. Run existing testsAdd a test so it doesn't come back:
javascripttest('login sets user ID in session', async () => { const user = await login({ email: 'test@example.com', password: 'pass' }); expect(session.userId).toBe(user.id); expect(session.userId).not.toBeNull(); });
Cut the problem space in half repeatedly:
javascript// Does the bug happen before or after this line? console.log('CHECKPOINT 1'); // ... code ... console.log('CHECKPOINT 2'); // ... code ... console.log('CHECKPOINT 3');
Explain the code line by line out loud. Often you'll spot the issue while explaining.
Strategic console.logs:
javascriptconsole.log('Input:', input); console.log('After transform:', transformed); console.log('Before save:', data); console.log('Result:', result);
Compare working vs broken:
Use git to find when it broke:
bashgit bisect start git bisect bad # Current commit is broken git bisect good abc123 # This old commit worked # Git will check out commits for you to test
javascript// Bug const name = user.profile.name; // Fix const name = user?.profile?.name || 'Unknown'; // Better fix if (!user || !user.profile) { throw new Error('User profile required'); } const name = user.profile.name;
javascript// Bug let data = null; fetchData().then(result => data = result); console.log(data); // null - not loaded yet // Fix const data = await fetchData(); console.log(data); // correct value
javascript// Bug for (let i = 0; i <= array.length; i++) { console.log(array[i]); // undefined on last iteration } // Fix for (let i = 0; i < array.length; i++) { console.log(array[i]); }
javascript// Bug if (count == 0) { // true for "", [], null // Fix if (count === 0) { // only true for 0
javascript// Bug const result = asyncFunction(); // Returns Promise console.log(result.data); // undefined // Fix const result = await asyncFunction(); console.log(result.data); // correct value
Console: View logs and errors
Sources: Set breakpoints, step through code
Network: Check API calls and responses
Application: View cookies, storage, cache
Performance: Find slow operationsjavascript// Built-in debugger node --inspect app.js // Then open chrome://inspect in Chrome
json// .vscode/launch.json { "type": "node", "request": "launch", "name": "Debug App", "program": "${workspaceFolder}/app.js" }
After fixing, document it:
markdown## Bug: Login timeout after 30 seconds **Symptom:** Users get logged out immediately after login **Root Cause:** Session cookie expires before auth check completes **Fix:** Increased session timeout from 30s to 3600s in config **Files Changed:** - config/session.js (line 12) **Testing:** Verified login persists for 1 hour **Prevention:** Added test for session persistence
@systematic-debugging - Advanced debugging@test-driven-development - Testing@codebase-audit-pre-push - Code review| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.