$npx -y skills add jmxt3/gitscape.ai --skill debugging-and-error-recoveryGuides systematic root-cause debugging. Use when tests fail, builds break, behavior doesn't match expectations, or you encounter any unexpected error. Use when you need a systematic approach to finding and fixing the root cause rather than guessing.
| 1 | # Debugging and Error Recovery |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Systematic debugging with structured triage. When something breaks, stop adding features, preserve evidence, and follow a structured process to find and fix the root cause. Guessing wastes time. The triage checklist works for test failures, build errors, runtime bugs, and production incidents. |
| 6 | |
| 7 | ## When to Use |
| 8 | |
| 9 | - Tests fail after a code change |
| 10 | - The build breaks |
| 11 | - Runtime behavior doesn't match expectations |
| 12 | - A bug report arrives |
| 13 | - An error appears in logs or console |
| 14 | - Something worked before and stopped working |
| 15 | |
| 16 | ## The Stop-the-Line Rule |
| 17 | |
| 18 | When anything unexpected happens: |
| 19 | |
| 20 | ``` |
| 21 | 1. STOP adding features or making changes |
| 22 | 2. PRESERVE evidence (error output, logs, repro steps) |
| 23 | 3. DIAGNOSE using the triage checklist |
| 24 | 4. FIX the root cause |
| 25 | 5. GUARD against recurrence |
| 26 | 6. RESUME only after verification passes |
| 27 | ``` |
| 28 | |
| 29 | **Don't push past a failing test or broken build to work on the next feature.** Errors compound. A bug in Step 3 that goes unfixed makes Steps 4-10 wrong. |
| 30 | |
| 31 | ## The Triage Checklist |
| 32 | |
| 33 | Work through these steps in order. Do not skip steps. |
| 34 | |
| 35 | ### Step 1: Reproduce |
| 36 | |
| 37 | Make the failure happen reliably. If you can't reproduce it, you can't fix it with confidence. |
| 38 | |
| 39 | ``` |
| 40 | Can you reproduce the failure? |
| 41 | ├── YES → Proceed to Step 2 |
| 42 | └── NO |
| 43 | ├── Gather more context (logs, environment details) |
| 44 | ├── Try reproducing in a minimal environment |
| 45 | └── If truly non-reproducible, document conditions and monitor |
| 46 | ``` |
| 47 | |
| 48 | **When a bug is non-reproducible:** |
| 49 | |
| 50 | ``` |
| 51 | Cannot reproduce on demand: |
| 52 | ├── Timing-dependent? |
| 53 | │ ├── Add timestamps to logs around the suspected area |
| 54 | │ ├── Try with artificial delays (setTimeout, sleep) to widen race windows |
| 55 | │ └── Run under load or concurrency to increase collision probability |
| 56 | ├── Environment-dependent? |
| 57 | │ ├── Compare Node/browser versions, OS, environment variables |
| 58 | │ ├── Check for differences in data (empty vs populated database) |
| 59 | │ └── Try reproducing in CI where the environment is clean |
| 60 | ├── State-dependent? |
| 61 | │ ├── Check for leaked state between tests or requests |
| 62 | │ ├── Look for global variables, singletons, or shared caches |
| 63 | │ └── Run the failing scenario in isolation vs after other operations |
| 64 | └── Truly random? |
| 65 | ├── Add defensive logging at the suspected location |
| 66 | ├── Set up an alert for the specific error signature |
| 67 | └── Document the conditions observed and revisit when it recurs |
| 68 | ``` |
| 69 | |
| 70 | For test failures: |
| 71 | ```bash |
| 72 | # Run the specific failing test |
| 73 | npm test -- --grep "test name" |
| 74 | |
| 75 | # Run with verbose output |
| 76 | npm test -- --verbose |
| 77 | |
| 78 | # Run in isolation (rules out test pollution) |
| 79 | npm test -- --testPathPattern="specific-file" --runInBand |
| 80 | ``` |
| 81 | |
| 82 | ### Step 2: Localize |
| 83 | |
| 84 | Narrow down WHERE the failure happens: |
| 85 | |
| 86 | ``` |
| 87 | Which layer is failing? |
| 88 | ├── UI/Frontend → Check console, DOM, network tab |
| 89 | ├── API/Backend → Check server logs, request/response |
| 90 | ├── Database → Check queries, schema, data integrity |
| 91 | ├── Build tooling → Check config, dependencies, environment |
| 92 | ├── External service → Check connectivity, API changes, rate limits |
| 93 | └── Test itself → Check if the test is correct (false negative) |
| 94 | ``` |
| 95 | |
| 96 | **Use bisection for regression bugs:** |
| 97 | ```bash |
| 98 | # Find which commit introduced the bug |
| 99 | git bisect start |
| 100 | git bisect bad # Current commit is broken |
| 101 | git bisect good <known-good-sha> # This commit worked |
| 102 | # Git will checkout midpoint commits; run your test at each |
| 103 | git bisect run npm test -- --grep "failing test" |
| 104 | ``` |
| 105 | |
| 106 | ### Step 3: Reduce |
| 107 | |
| 108 | Create the minimal failing case: |
| 109 | |
| 110 | - Remove unrelated code/config until only the bug remains |
| 111 | - Simplify the input to the smallest example that triggers the failure |
| 112 | - Strip the test to the bare minimum that reproduces the issue |
| 113 | |
| 114 | A minimal reproduction makes the root cause obvious and prevents fixing symptoms instead of causes. |
| 115 | |
| 116 | ### Step 4: Fix the Root Cause |
| 117 | |
| 118 | Fix the underlying issue, not the symptom: |
| 119 | |
| 120 | ``` |
| 121 | Symptom: "The user list shows duplicate entries" |
| 122 | |
| 123 | Symptom fix (bad): |
| 124 | → Deduplicate in the UI component: [...new Set(users)] |
| 125 | |
| 126 | Root cause fix (good): |
| 127 | → The API endpoint has a JOIN that produces duplicates |
| 128 | → Fix the query, add a DISTINCT, or fix the data model |
| 129 | ``` |
| 130 | |
| 131 | Ask: "Why does this happen?" until you reach the actual cause, not just where it manifests. |
| 132 | |
| 133 | ### Step 5: Guard Against Recurrence |
| 134 | |
| 135 | Write a test that catches this specific failure: |
| 136 | |
| 137 | ```typescript |
| 138 | // The bug: task titles with special characters broke the search |
| 139 | it('finds tasks with special characters in title', async () => { |
| 140 | await createTask({ title: 'Fix "quotes" & <brackets>' }); |
| 141 | const results = await searchTasks('quotes'); |
| 142 | expect(results).toHaveLength(1); |
| 143 | expect(results[0].title).toBe('Fix "quotes" & <brackets>'); |
| 144 | }); |
| 145 | ``` |
| 146 | |
| 147 | This test wil |