Bug: /login Does Not Recover Active Session After OAuth Token Expiration

Resolved 💬 9 comments Opened Dec 21, 2025 by brianmjohnson Closed Feb 22, 2026

Bug Report: /login Does Not Recover Active Session After OAuth Token Expiration

Summary

When an OAuth token expires during an active Claude Code session, running /login and successfully authenticating in the browser does not recover the session. The session remains stuck in a 401 error loop, forcing users to abandon the session and lose context.

Problem Description

Current Behavior

  1. User is in an active Claude Code session
  2. OAuth token expires (after ~1 hour of use or idle time)
  3. Session shows repeated errors: API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired..."}}
  4. User runs /login command
  5. Browser opens, user completes OAuth authorization successfully
  6. User returns to CLI and types continue or resume
  7. Session continues showing 401 errors - token not picked up
  8. No amount of retrying helps - session is permanently stuck

Expected Behavior

After successful /login authentication:

  1. The active session should detect the new token
  2. continue or resume should work immediately
  3. Session context should be preserved

Why This Matters

  • Lost context: Users must abandon sessions with in-progress work
  • Breaks workflows: Unattended execution is impossible
  • Poor developer experience: /login appears to succeed but doesn't actually fix the problem
  • Data loss risk: Uncommitted work or in-memory state is lost when session is abandoned

Reproduction Steps

  1. Start a Claude Code session
  2. Work for 45-60+ minutes (or wait until token expires)
  3. When 401 error appears, run /login
  4. Complete browser OAuth flow
  5. Return to CLI
  6. Type continue or resume
  7. Observe: Session still shows 401 errors

Evidence from Session Logs

Session log shows 6+ consecutive 401 errors after /login:

API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired. Please obtain a new token or refresh your existing token."},"request_id":"req_011CWLUr4VZkAL644D4Di2nC"} · Please run /login
API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired. Please obtain a new token or refresh your existing token."},"request_id":"req_011CWLUt58aFJwcWZG8NMqA4"} · Please run /login
API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired. Please obtain a new token or refresh your existing token."},"request_id":"req_011CWLUzY7DCEZ1Mr6dF6B15"} · Please run /login
...

Each request has a unique request_id, confirming these are separate retry attempts, all failing.

Technical Analysis

Root Cause Hypotheses

| Hypothesis | Description |
| ----------------------- | ------------------------------------------------------------------------------ |
| In-memory token caching | Active session caches token in memory, doesn't reload from disk after /login |
| Token file not updated | /login saves token but active session reads from different location |
| Race condition | Browser callback completes but CLI doesn't wait for token write |
| Session ID mismatch | Token saved with session ID that doesn't match active session |
| Process isolation | /login runs in subprocess that can't update parent process state |

What We've Tried

| Workaround | Result |
| ------------------------------ | --------- |
| Multiple continue commands | Still 401 |
| resume command | Still 401 |
| Wait 5+ minutes after /login | Still 401 |
| /login multiple times | Still 401 |

What Might Work (Destructive)

| Option | Trade-off |
| ------------------------- | ------------------------------ |
| Kill session, start fresh | Loses all context |
| /logout then /login | Untested, likely loses context |
| New terminal window | Loses session entirely |

Impact

Severity: High

  • Frequency: Occurs on every session >1 hour
  • User impact: Complete session loss, work interruption
  • Workaround availability: None that preserve session

Affected Use Cases

| Use Case | Impact |
| ------------------------ | -------------------------------- |
| Long coding sessions | Must restart every hour |
| Autonomous builds | Cannot run unattended |
| Complex multi-step tasks | Risk of losing progress mid-task |
| Agent frameworks | Breaks reliability guarantees |

Proposed Fix

Option A: Token Hot-Reload (Preferred)

Active session should detect token file changes and reload:

1. /login saves new token to ~/.claude/auth-token (or equivalent)
2. Active session watches file or checks on next API call
3. If token changed, reload it before retrying

Option B: IPC Token Update

/login subprocess should notify parent process:

1. /login completes OAuth flow
2. Sends signal/message to active session PID
3. Active session receives new token directly

Option C: Force Token Refresh Command

Add /refresh-token command that:

1. Re-reads token from disk
2. Updates in-memory token
3. Retries last failed request

Environment

  • OS: macOS Darwin 25.1.0
  • Claude Code Version: 2.0.53
  • Session duration before issue: ~4+ hours with intermittent activity
  • Authentication method: OAuth (browser-based)

Related Issues

This may be related to:

  • Token refresh/rotation handling
  • Long-running session management
  • OAuth flow completion detection

Workaround for Other Users

Until fixed, the only reliable workaround is:

  1. Commit all work frequently (git commit after each logical change)
  2. Use issue trackers (like bd beads) to persist state
  3. Accept that sessions >1 hour may need to be restarted
  4. When stuck in 401 loop, kill session and start fresh

This is not acceptable for production use of autonomous agents.

View original on GitHub ↗

This issue has 9 comments on GitHub. Read the full discussion on GitHub ↗