How to Debug Claude Code Session Issues and See What Actually Happened
Problem
Claude Code was making edits I didn’t understand. I’d ask it to fix a bug, and somehow three other files got changed. I’d see “Read 3 files” in the output but had zero visibility into which files or what was in them. When Claude seemed to forget something I’d told it earlier in the conversation, I had no way to figure out where the context was lost.
Here’s what a typical session looked like from my perspective:
I'll help you fix that bug.
Read 3 files
Made 5 edits
Ran tests - all passingThat’s it. No details. No context. Just summaries.
I tried asking Claude what it did:
Me: What files did you read?Claude: I read the relevant files for the bug fix.
Me: Which files specifically?Claude: The ones related to the authentication module.
Me: Can you list them?Claude: I read auth.ts, user.ts, and session.ts.But even then, I couldn’t see what Claude actually saw in those files. Did it read the whole file? Just a portion? What lines? And why did it make those specific edits?
The real problem hit when Claude forgot about a constraint I’d mentioned earlier:
Me (message 5): Make sure to preserve backward compatibility with v1 API
... 20 messages later ...
Me: Why did you change the API response format?Claude: I optimized it for v2.
Me: I told you to preserve backward compatibility!Claude: I apologize, I don't see that in my current context...I had no way to debug this. Did the context get pushed out of the window? Did Claude misunderstand? I was flying blind.
What happened?
I started searching for ways to inspect Claude Code sessions and found a Reddit discussion about a tool called claude-devtools. Users described exactly what I needed:
“Full visibility into what actually happened - every file that was read, every edit with proper inline diff, every bash command that ran”
“You can read the extended thinking blocks alongside tool traces, so you can understand why Claude made certain decisions”
“If you’ve ever been confused about why Claude forgot something mid conversation, this clears it up fast”
This sounded like exactly what I needed. But first, I had to understand where the session data was stored.
Claude Code logs everything to ~/.claude/ in JSONL format. These files exist on my machine already - I just needed a way to make sense of them.
How to solve it?
I installed claude-devtools and opened my session logs:
# Install globallynpm install -g claude-devtools
# View a specific sessionclaude-devtools view <session-id>
# List recent sessionsclaude-devtools list
# Export session for offline analysisclaude-devtools export <session-id> -o session-analysis.jsonWhen I opened my problematic session, I could finally see everything:
1. Every file read with full content:
[10:30:15] Read: src/auth.ts (lines 1-150)┌─────────────────────────────────────────────────────┐│ 1 import { User } from './types'; ││ 2 import { Session } from './session'; ││ ... ││ 45 export async function validateToken(token) { ││ 46 // Check if token is expired ││ 47 const session = await Session.findByToken(); ││ │└─────────────────────────────────────────────────────┘No more “Read 3 files” with zero context. I could see exactly what Claude saw.
2. Every edit with inline diffs:
[10:30:45] Edit: src/auth.ts function validateToken(token: string) { return Session.findByToken(token); } function validateToken(token: string, options?: ValidateOptions) { const session = await Session.findByToken(token); if (options?.skipExpiry) return session; return session && !session.expired ? session : null; }I could see the old code, the new code, and understand exactly what changed.
3. Extended thinking blocks:
[10:30:40] Extended Thinking:The user mentioned backward compatibility with v1 API.I need to add an optional parameter rather than changingthe existing signature. This way existing callers won't break.
Wait - the user said this 20 messages ago. Let me checkif this is still in context...
[Context check] Message 5 is at position 45/200 in contextwindow. Still available. I should preserve the v1 behavior.This was the breakthrough. I could see Claude’s reasoning process - including when it checked whether earlier messages were still in context.
4. All bash commands:
[10:31:00] Bash: npm test -- --grep auth[10:31:02] Result: 12 tests passed, 0 failed
[10:31:03] Bash: git diff src/auth.ts[10:31:04] Result: +5 lines, -2 linesEvery command, every output, all visible.
The reason
The reason I couldn’t debug before was that Claude Code’s default output is optimized for brevity. It shows summaries, not details. This is fine for normal use but terrible for debugging.
DevTools solves this by reading the raw JSONL session logs that Claude Code already writes to disk. It then presents them in a format optimized for human inspection:
┌─────────────────────────────────────────────────────┐│ ~/.claude/projects/abc123/sessions/2026-03-24.jsonl ││ (Claude Code writes this automatically) │└─────────────────────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────┐│ Claude DevTools ││ - Parses JSONL into structured data ││ - Indexes for search ││ - Shows inline diffs ││ - Displays extended thinking ││ - Highlights syntax │└─────────────────────────────────────────────────────┘The key insight is that the data was always there. Claude Code logs everything. I just couldn’t read it easily.
With DevTools, I can now:
-
Trace context loss: See exactly when a message falls out of the context window
-
Understand decisions: Read the thinking blocks to see why Claude made a choice
-
Verify assumptions: Check if Claude actually read the right files
-
Audit changes: See every edit with proper diffs, not just “made 5 edits”
-
Debug errors: Find the exact command that failed and its output
Common mistakes I made
Mistake 1: Trusting summaries without verification
I’d see “Read 3 files” and assume Claude read the right ones. Now I check:
[DevTools] Session 2026-03-24: Files read: auth.ts, user.ts, config.ts Lines read: auth.ts(1-150), user.ts(45-89), config.ts(full)
Wait - Claude only read lines 45-89 of user.ts? That might explain the bug...Mistake 2: Assuming Claude “understood” my requirements
I’d give an instruction and move on. Now I check the thinking output:
[Extended Thinking]User wants backward compatibility. I'll add an optional parameter.But wait - they said v1 API specifically. Let me check what v1 format is...
[Tool: Read] api/v1/types.tsIf I don’t see this verification step in the thinking, I know Claude may have missed it.
Mistake 3: Ignoring session history when debugging
When Claude forget something, I’d just restate it. Now I open DevTools first:
[DevTools] Checking message 5 position in context...Message 5 is at position 180/200Context window: 200K tokensUsed: 185K tokens
Conclusion: Message 5 is barely in context. Claude might not beable to retrieve it effectively. I should restate the requirement.Mistake 4: Not checking the actual edits
I’d see “all tests passing” and assume the changes were correct. Now I review every diff:
[DevTools] Showing all edits in session:
Edit 1: auth.ts - Added optional parameter ✓Edit 2: user.ts - Changed return type (unexpected!)Edit 3: test.ts - Updated tests for new return type
Wait - why did user.ts change? That wasn't part of my request...Practical workflow
Here’s how I now debug Claude Code sessions:
Step 1: List sessions to find the right one
claude-devtools list --recent 5Session ID: abc123, Date: 2026-03-24 10:30, Files: 8, Edits: 12Session ID: def456, Date: 2026-03-23 14:15, Files: 3, Edits: 5Session ID: ghi789, Date: 2026-03-22 09:00, Files: 15, Edits: 23Step 2: Open the session and filter by tool
claude-devtools view abc123 --filter EditThis shows only the edits with full diffs.
Step 3: Check extended thinking for decisions
claude-devtools view abc123 --show-thinkingI can see why Claude made each decision.
Step 4: Export for detailed analysis
claude-devtools export abc123 -o analysis.jsonThis gives me a JSON file I can search, grep, or analyze programmatically.
Summary
In this post, I showed how to debug Claude Code sessions using claude-devtools. The key point is that Claude Code already logs everything - you just need the right tool to read those logs.
The main capabilities:
- Full file content visibility - See exactly what Claude read, not just “Read 3 files”
- Inline diffs for edits - Understand every change with before/after comparison
- Extended thinking access - Read Claude’s reasoning for each decision
- Context window debugging - Find out why earlier messages were forgotten
- Command tracing - See every bash command and its output
If you use Claude Code heavily and find yourself wondering “why did it do that?” or “what files did it actually read?”, claude-devtools gives you the visibility you need.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments