/wbDebug — Examples
Self-help.
/wbDebugis the command you reach for the second you hit an error. Not the third. This file shows what "hypothesis first" looks like in practice.
The cardinal rule
Hypothesis before fix. Every /wbDebug run must produce an explicit hypothesis (what + where + why) before touching any code. This is the whole point — the command exists specifically to prevent the "try random things until the error goes away" pattern.
If the AI skips hypothesis and jumps to fix, the run is invalid. Re-prompt: "first tell me what you think is wrong and why, before proposing any change."
Example 1 — /wbDebug "Maximum recursive updates exceeded in <DataViewer>"
$ /wbDebug "Maximum recursive updates exceeded in <DataViewer>"
[AI] Loading context.md + dev.md for wb-dataviewer...
[AI] apiResponse_ caching convention noted
[AI]
[AI] Scanning reports/ for related debug reports...
[AI] → 2026-04-19: "apiResponse_ cache invalidation" — similar symptom
[AI] Hypothesis there: watcher key mismatch. Partially resolved.
[AI]
[AI] Forming hypothesis for current error...
[AI]
[AI] HYPOTHESIS:
[AI] A watcher on apiResponse_ is triggering a reactive write to
[AI] the same value it's watching. This is the classic Vue "mutate
[AI] inside watcher" loop.
[AI]
[AI] Most likely location: src/composables/useApiCache.js (line 34),
[AI] where the watcher both reads apiResponse_ and calls setApiResponse_
[AI] inside the callback.
[AI]
[AI] EVIDENCE TO CHECK:
[AI] 1. Open src/composables/useApiCache.js
[AI] 2. Find the watcher — confirm it writes to apiResponse_
[AI] 3. Check the trigger: is the watcher firing on every render?
[AI]
[AI] NOT YET PROPOSING A FIX. Waiting for you to verify or refute
[AI] the hypothesis first.User confirms hypothesis by opening the file and checking:
$ "confirmed, the watcher does write to apiResponse_"
[AI] Hypothesis confirmed. Now proposing fix.
[AI]
[AI] FIX:
[AI] The watcher should read apiResponse_ but NOT write to it. The
[AI] intended behavior is: when the underlying data changes,
[AI] compute a derived value, store THAT in a separate ref.
[AI]
[AI] Existing vs Suggested:// Existing (line 34)
watch(apiResponse_, (newVal) => {
apiResponse_.value = normalizeData(newVal); // <-- loop
});
// Suggested
const normalizedResponse = computed(() => normalizeData(apiResponse_.value));[AI] Additional check: all 3 consumer sites use apiResponse_.value
[AI] directly. You'll need to migrate them to normalizedResponse.
[AI]
[AI] Writing reports/20260424/debugs/debug_apiResponse_loop_202604240400.md
[AI]
[AI] NEXT:
[AI] 1. Apply the fix (describe "apply the suggested fix").
[AI] 2. /wbTest to confirm the loop is gone.
[AI] 3. /wbGit to commit.What's worth noticing:
- The AI pauses after the hypothesis and waits for verification. This is the critical gate. Without it, the "fix" would be based on a possibly-wrong guess.
- Related reports from prior days are surfaced automatically. The 2026-04-19 report is connected to the same root cause area.
- The proposed fix is specific (line 34) + comes with an awareness of downstream consumers that need migration. Closed loop in action.
Example 2 — /wbDebug packages/wb-core/src/utils/extractSubObject.js (file-scoped, no error message)
Sometimes you know where but not what. Point at the file with no error text.
$ /wbDebug packages/wb-core/src/utils/extractSubObject.js
[AI] Reading the file...
[AI] Checking reports/ for open complaints about extractSubObject...
[AI] → 2026-04-22 audit: test coverage gap at line 47
[AI] → 2026-04-20 user report (in standup): "extractSubObject
[AI] returns undefined for deeply nested paths"
[AI]
[AI] HYPOTHESIS (based on reports, not on running code):
[AI] The user-reported symptom is consistent with the array-handling
[AI] open decision. If the path traverses through an array of
[AI] objects, the current code treats arrays as leaves — so it
[AI] returns the array itself, not the value inside.
[AI]
[AI] Example: extractSubObject({users: [{name: 'x'}]}, 'users.0.name')
[AI] Expected: 'x'
[AI] Actual: undefined (because 'users' returns the array, and '.0.name'
[AI] can't traverse it under current logic)
[AI]
[AI] EVIDENCE TO CHECK:
[AI] 1. Confirm the failing case by running it
[AI] 2. If hypothesis is correct, this is NOT a bug — it's the
[AI] documented open decision about array handling
[AI]
[AI] REFUSING TO FIX until you decide the array-handling question.
[AI] This is a design decision, not a bug. Fixing it silently
[AI] would commit the codebase to one side of the open decision.
[AI]
[AI] Options:
[AI] a. Close the decision: structural arrays → apply fix
[AI] b. Keep arrays as leaves → document as known limitation, add
[AI] a helpful error message
[AI] c. Defer: wait until more evidence accumulatesWhat's worth noticing:
- The hypothesis references both an audit report AND a standup note. Closed loop draws from multiple report types.
- The AI refuses to fix because the symptom maps to an open decision. This is the right posture — silently "fixing" the symptom would resolve an architectural question without your input.
- Three options listed for the user. The command doesn't decide; it surfaces.
Example 3 — /wbDebug when the hypothesis is wrong
Half the value of hypothesis-first is discovering the hypothesis is wrong without writing a bad fix.
$ /wbDebug "apiResponse_ is not defined on component mount"
[AI] Forming hypothesis...
[AI]
[AI] HYPOTHESIS:
[AI] apiResponse_ is being accessed before the cache is hydrated.
[AI] Most likely: a child component mounts before the parent's
[AI] apiResponse_ ref is assigned.User checks:
$ "hypothesis is wrong. apiResponse_ is fine on mount. The error
fires later, after a route change."
[AI] Hypothesis refuted. Reforming.
[AI]
[AI] NEW HYPOTHESIS (based on new evidence):
[AI] A route change triggers a component unmount that nullifies
[AI] apiResponse_, but a lingering Promise resolves after the
[AI] unmount and tries to access the now-nulled value.
[AI]
[AI] EVIDENCE TO CHECK:
[AI] 1. Is there an async operation (fetch, setTimeout) that fires
[AI] in beforeRouteLeave or similar?
[AI] 2. Does it access apiResponse_ without a null check?What's worth noticing:
- The AI explicitly acknowledges the refutation and reforms. No saving face, no "well actually I was right" hedging.
- The new hypothesis is genuinely different — not just a reworded version of the first one. It incorporates the user's new evidence (route change timing).
- This is the debugging behavior you want: iteratively refined hypotheses, not a single-shot guess.
Example 4 — /wbDebug when there's no report and no tests
The command still works, but the output is weaker.
$ /wbDebug "TypeError: Cannot read property 'map' of undefined"
[AI] Checking context.md + reports...
[AI] Minimal context available.
[AI] No related debug reports.
[AI] Error message is generic (applies to many situations).
[AI]
[AI] HYPOTHESIS (low confidence — not enough context):
[AI] Somewhere in the code, .map() is being called on a variable
[AI] that's supposed to be an array but is currently undefined.
[AI] This typically happens when:
[AI] a. API response is still pending but the component tries to
[AI] render the data
[AI] b. A prop is named wrong (undefined by default)
[AI] c. Destructuring from an object that doesn't have the expected key
[AI]
[AI] NOT ENOUGH INFORMATION to narrow further without a stack trace
[AI] or file path.
[AI]
[AI] PLEASE PROVIDE:
[AI] - Stack trace (full)
[AI] - File + line where the error originates
[AI] - Recent changes (git diff) if anyWhat's worth noticing:
- The AI refuses to guess when it genuinely doesn't have enough signal. Better to ask than to propose three random fixes.
- The hypothesis is framed as "X typically happens when..." — it's listing possibilities, not committing to one.
- Explicit request for more information. This is acceptable; debugging is collaborative.
The pattern
Every /wbDebug has:
- Context load — read
context.md, recent reports, related debug history. - Hypothesis — what + where + why. Specific.
- Evidence-to-check list — how you can verify/refute the hypothesis.
- Wait — no fix until hypothesis is confirmed.
- Fix proposal (if hypothesis confirmed) or refusal (if hypothesis maps to open decision) or reform (if refuted).
- Report written — to
reports/YYYY/MM/DD/debugs/.
The pause between hypothesis and fix is non-negotiable. That pause is the command.
Basic Usage
# Standard command execution
/wbDebug frontEnd/wbc-ui3/packages/
# Execution with explicit target ID filter
/wbDebug deployement/apps/wb-jobs/ --id=1,2,3Model Fallback Chain (.wb/bin/wbRun)
When executing CLI dispatches, /wbDebug wraps binary calls in .wb/bin/wbRun to ensure output-error guarding:
.wb/bin/wbRun claude -p --permission-mode auto "/wbDebug target/" || .wb/bin/wbRun agy --model gemini-3.1-pro-high -p "/wbDebug target/" || .wb/bin/wbRun opencode run -m opencode-go/deepseek-v4-pro "/wbDebug target/"Role Model Overrides (--planner, --worker, --validator, --mechanical)
You can override default models per role directly from the command line:
# Override Worker and Validator models
/wbDebug packages/ --wave=A --worker="DeepSeek V4 Pro,Kimi K3" --validator="Gemini 3.5 Pro"
# Override all 4 roles simultaneously
/wbDebug apps/wb-jobs/ --wave=all --planner="Claude Opus 5" --worker="DeepSeek V4 Pro" --validator="Claude Sonnet 4.7" --mechanical="Gemini 3 Flash"Autonomous Non-Interactive Execution (-y / --yes)
Run /wbDebug in zero-touch print mode without stopping for manual decision prompts:
.wb/bin/wbRun claude -p --permission-mode auto "/wbDebug frontEnd/wbc-ui3/packages/ --wave --as='expert,steps' -y"