Skip to content

fix: prevent silent session fallback in interactive PTY mode#21

Merged
dakl merged 3 commits intomainfrom
switches-sessions
Mar 27, 2026
Merged

fix: prevent silent session fallback in interactive PTY mode#21
dakl merged 3 commits intomainfrom
switches-sessions

Conversation

@dakl
Copy link
Copy Markdown
Owner

@dakl dakl commented Mar 24, 2026

Summary

Fixed a bug where Codez sessions would silently switch to a different Claude Code session when resuming.

Root cause: Claude Code's --resume flag behaves differently in interactive mode vs -p mode:

  • -p mode: Properly errors when session doesn't exist
  • Interactive mode: Silently falls back to the most recent session in that directory

When a stored Claude session was no longer on disk (cleaned up, path changed, etc), interactive --resume <missing-id> would fall back instead of error, causing users to see a completely different conversation.

Solution

Added claudeSessionExistsOnDisk() utility to validate that ~/.claude/projects/{path-hash}/{session-id}.jsonl exists before spawning an interactive PTY with --resume. If the session file is missing, fall back to --session-id (create fresh) instead, preventing the silent fallback.

The fix also logs a warning when a stale session is detected and recovered.

Changes

  • feat: validate Claude session exists before PTY spawn — Adds session file existence checker with path hashing logic
  • feat: guard --resume with session existence check — Integrates validation into PTY creation handler
  • test: session ID validation tests — Comprehensive tests proving the bug and validating the fix (tests 5-7 added to test-clear-session-id.mjs)

Testing

All 223 unit tests pass. New tests validate:

  • Session path hashing algorithm
  • Session file detection (exists, missing, no project dir)
  • Proof that --resume <bad-uuid> silently falls back in interactive mode (the bug)

Related earlier work:

🤖 Generated with Claude Code

dakl added 3 commits March 24, 2026 21:20
Claude Code's --resume flag behaves differently in interactive mode vs -p mode:
- In -p mode: properly errors when session doesn't exist
- In interactive mode: silently falls back to most recent session

This caused Codez sessions to sometimes switch to a different Claude session
when the stored session was no longer on disk (cleaned up, path changed, etc).

Add claudeSessionExistsOnDisk() utility to check if ~/.claude/projects/{path-hash}/{id}.jsonl
exists before spawning the PTY with --resume. If the session doesn't exist,
fall back to --session-id (create fresh) instead, avoiding silent fallback.

Includes comprehensive tests for path hashing and session file detection.
Before spawning an interactive PTY with --resume, verify that the Claude
session still exists on disk. If not found, use --session-id to create
a fresh session instead of letting Claude silently fall back to the most
recent session.

Logs a warning when a stale session is detected and recovered.
Expand test-clear-session-id.mjs with three new tests:
- Test 5: Proves --resume with non-existent UUID silently falls back in
  interactive mode (the root cause of the session-switching bug)
- Test 6: Validates that --session-id with existing UUID errors
- Test 7: Confirms --session-id behavior in interactive mode

These tests demonstrate the distinction between -p and interactive modes
and document the expected behavior when session validation is in place.
greptile-apps[bot]

This comment was marked as off-topic.

@dakl
Copy link
Copy Markdown
Owner Author

dakl commented Mar 27, 2026

@greptile

@dakl dakl merged commit b71cb2d into main Mar 27, 2026
3 checks passed
Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@dakl dakl deleted the switches-sessions branch March 27, 2026 06:35
dakl added a commit that referenced this pull request Mar 27, 2026
dakl added a commit that referenced this pull request Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant