CLI Debugging Workflow
Your CI just went red. The error message is “Cannot read properties of undefined (reading ‘map’)” with a stack trace that touches six files across two services. Your teammate says it was working yesterday. Git blame points at a merge commit with 40 changed files. You could spend the next two hours adding console.log statements. Or you could pipe the error into Claude Code and have a root cause analysis in five minutes.
The developers who debug fastest with Claude Code do not just paste errors and ask for fixes. They use a systematic workflow: give Claude the error with full context, let it trace the execution path through your codebase, verify the diagnosis before applying the fix, and write a test that prevents the regression. This lesson covers that workflow.
What You’ll Walk Away With
Section titled “What You’ll Walk Away With”- A workflow for going from error message to root cause in minutes
- Prompts that give Claude enough context to diagnose real bugs, not just guess
- The pipe-and-diagnose technique for production errors
- Headless mode patterns for automated error triage in CI
The Debugging Workflow
Section titled “The Debugging Workflow”-
Give Claude the full error context
The quality of the diagnosis depends entirely on the quality of the input. A bare error message gets you a guess. A stack trace with context gets you a root cause.
-
Let Claude trace the execution path
Claude reads the files in the stack trace, follows imports, checks types, and builds a picture of what went wrong. Do not rush this step — the trace is where the bug is found.
Trace the request flow from src/routes/orders.ts line 47through the service layer and into the database query.Show me the data shape at each step. Where does the valuebecome undefined? -
Verify the diagnosis before applying the fix
Claude might identify the wrong root cause, especially for intermittent bugs. Before writing any fix, verify.
You're saying the bug is in the middleware that parses theJWT token. Prove it: show me the specific line where theundefined value originates, and explain why it only happensfor users with expired sessions. -
Fix the bug and write a regression test
Fix the bug. Then write a test that reproduces the exactscenario that caused it -- expired session token with avalid user ID. The test should fail without the fix andpass with it. -
Check for similar bugs elsewhere
Search the codebase for other places that use the samepattern that caused this bug. Are there other middlewarefunctions that assume the token payload is always present?List them so I can fix them proactively.
Piping Errors Directly into Claude
Section titled “Piping Errors Directly into Claude”Claude Code’s terminal-native design means you can pipe error output directly into it. This is the fastest path from error to diagnosis.
From your dev server
Section titled “From your dev server”# Pipe a failing test directly to Claudenpm test -- --run tests/services/order.test.ts 2>&1 | \ claude -p "This test is failing. Read the test file and the \ source code it tests. Diagnose the root cause and fix it."From production logs
Section titled “From production logs”# Grab recent errors and analyze themgrep "ERROR" /var/log/app/production.log | tail -50 | \ claude -p "Analyze these production errors. Group them by \ root cause. For each group, identify the source file and \ suggest a fix. Prioritize by frequency."From CI output
Section titled “From CI output”# Pipe CI failure output to Claudegh run view 12345 --log-failed | \ claude -p "This CI run failed. Identify which test failed, \ read the relevant source code, and explain what broke. \ Check recent commits to see if a specific change caused it."Debugging Specific Bug Types
Section titled “Debugging Specific Bug Types”Race conditions
Section titled “Race conditions”Race conditions are notoriously hard to debug because they are timing-dependent. Give Claude the full picture.
We have an intermittent test failure in tests/services/payment.test.ts.It passes 9 out of 10 times. The error is "expected 'processing'but received 'completed'".
Read the test and the payment service. Look for any async operationsthat might resolve in a different order depending on timing.Check for missing awaits, unhandled promises, or shared mutable state.Memory leaks
Section titled “Memory leaks”Our Node.js service memory grows from 200MB to 1.2GB over 6 hours,then crashes with OOM. I took heap snapshots at startup and atthe 4-hour mark.
Read our event handler code in src/handlers/ and look for:1. Event listeners that are added but never removed2. Arrays or maps that grow without bounds3. Closures that capture large objects4. Streams that are opened but never closed”It works locally but fails in CI”
Section titled “”It works locally but fails in CI””This test passes on my machine but fails in CI. Here's the CI output:[paste output]
Here's my local Node version: v20.11.0CI uses: v20.10.0
Read the test file and look for:1. Environment-dependent code (paths, timezones, locale)2. Timing-sensitive assertions3. Missing test fixtures or setup steps4. Order-dependent tests that assume state from a previous testUsing Sub-agents for Complex Debugging
Section titled “Using Sub-agents for Complex Debugging”When a bug spans multiple parts of the system, use sub-agents to investigate in parallel without filling your main context with irrelevant code.
Use sub-agents to investigate this bug from multiple angles:
1. Trace the request from the API gateway through the auth middleware to the order service. Find where the user object loses its organization_id field.
2. Check the database migration history for the organizations table. Was a column recently renamed or made nullable?
3. Search for all places in the codebase that read user.organization_id and check if any of them handle the undefined case.
Report findings so we can pinpoint the root cause.Each sub-agent runs in its own context, reads as many files as needed, and reports back a focused summary. Your main session stays clean for the actual fix.
Headless Debugging Automation
Section titled “Headless Debugging Automation”For teams that want automated error triage, headless mode turns Claude Code into a debugging pipeline.
# Automated error analysis in CIclaude -p "Analyze the test failures in this output andcategorize them:1. Flaky tests (timing-dependent, order-dependent)2. Real bugs (code logic errors)3. Environment issues (missing config, wrong versions)
For real bugs, identify the root cause file and line number.For flaky tests, suggest how to make them deterministic.
$(cat test-output.log)" \ --output-format json > debug-report.jsonThis generates a structured JSON report that your CI pipeline can post as a PR comment or send to Slack.
Reading Error Context with Git
Section titled “Reading Error Context with Git”Claude Code is git-aware. Use this for debugging regressions.
This bug started appearing after last Tuesday's deploy. Run:git log --oneline --after="2026-02-03" -- src/services/
Then read the diffs for each commit that touched the servicesdirectory. Which commit introduced the change that could cause"TypeError: Cannot read property 'id' of null" in the orderprocessing flow?For deeper investigation:
Run git bisect between the last known good commit (abc123)and the current HEAD. The test that reproduces the bug istests/services/order.test.ts. Find the exact commit thatintroduced the regression.When This Breaks
Section titled “When This Breaks”Claude fixes the symptom but not the root cause. This happens when you paste just the error message without context. Always include: the stack trace, when it happens, what changed recently, and how often it occurs. The more context, the more accurate the diagnosis.
The fix breaks something else. Claude fixed the bug but did not check for side effects. After every fix, run the full test suite, not just the test for the bug. Add this to your prompt: “After fixing the bug, run the full test suite and show me any new failures.”
Claude cannot reproduce the bug from the description. Write a failing test first. “Before debugging, write a test that reproduces this exact scenario. Run it to confirm it fails. Then trace the code to find the root cause.” A failing test is the most unambiguous bug report.
Extended thinking helps for complex bugs. For bugs that span many files or involve subtle timing issues, set the effort level to high before debugging. Claude will reason through the problem more carefully before suggesting a fix.
Context fills up during a long debugging session. If you have been reading many files to trace a bug, run /compact Focus on the bug diagnosis and the fix. Drop file contents we already analyzed. Alternatively, if you have a clear diagnosis, start a fresh session with just the diagnosis and let Claude implement the fix from scratch.
What’s Next
Section titled “What’s Next”Your bug is fixed and a regression test is in place. Now strengthen the rest of your test suite so you catch bugs before they reach production.