Skip to content

Fix session state management on disconnect#56

Closed
gricha wants to merge 2 commits intomainfrom
session-state-management
Closed

Fix session state management on disconnect#56
gricha wants to merge 2 commits intomainfrom
session-state-management

Conversation

@gricha
Copy link
Copy Markdown
Owner

@gricha gricha commented Jan 8, 2026

Summary

  • Remove automatic session interrupt when WebSocket closes - sessions now continue running on backend
  • Add AppState listener on mobile to auto-reconnect when app returns to foreground
  • Add visibilitychange listener on web to auto-reconnect when tab becomes visible
  • Add tests for WebSocket disconnect behavior

What this fixes

When a user backgrounds the mobile app or switches browser tabs, the WebSocket disconnects. Previously this killed the running Claude process, losing any in-progress work. Now:

  1. Backend processes continue running even when client disconnects
  2. Client automatically reconnects when user returns
  3. Messages are reloaded to show any updates that occurred while away

Test plan

  • Start a chat, background app, wait, return - should see response
  • Start a chat in web, switch tabs, return - should reconnect and show updates
  • Explicit interrupt (Stop button) should still work
  • WebSocket errors should still cleanup properly

🤖 Generated with Claude Code

gricha and others added 2 commits January 8, 2026 12:16
- Remove automatic interrupt on WebSocket close (sessions continue running)
- Add AppState listener for mobile to reconnect when app returns to foreground
- Add visibilitychange listener for web to reconnect when tab becomes visible
- Add tests for WebSocket disconnect behavior

Sessions now persist when user backgrounds app or closes tab. On return,
client automatically reconnects and reloads messages to show any updates
that occurred while disconnected.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix React hook dependency array issues causing listener re-registration
- Use refs to track state without triggering effect re-runs
- Check for CLOSED/CLOSING states instead of just !OPEN
- Reload messages BEFORE reconnecting WebSocket (sequential, not parallel)
- Add isReconnecting state with visual indicator (yellow dot)
- Track wasBackground/wasHidden state to only reconnect when returning

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment on lines +397 to +407
role: 'assistant',
content: parts.filter(p => p.type === 'text').map(p => p.content).join(''),
id: `msg-done-${Date.now()}`,
parts,
}])
}
streamingPartsRef.current = []
setStreamingParts([])
setIsStreaming(false)
return
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The mobile WebSocket reconnection handler is incomplete and misses critical message types like assistant, preventing streaming responses from being displayed after reconnecting.
Severity: CRITICAL

🔍 Detailed Analysis

The mobile reconnection logic in SessionChatScreen.tsx establishes a new WebSocket with an onmessage handler that is missing handlers for critical message types, specifically assistant, tool_use, and tool_result. While the main connect() function handles these types correctly, the separate reconnection logic does not. As a result, when a mobile user returns to the app and the WebSocket reconnects, they will not see any live streaming assistant responses or tool-related messages, even though the session continues on the backend. This breaks the core functionality of receiving real-time updates after a temporary disconnection.

💡 Suggested Fix

Refactor the mobile reconnection logic to reuse the main connect() function, similar to the web implementation. This will ensure the WebSocket uses the complete onmessage handler that processes all required message types, including assistant, tool_use, and tool_result.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: mobile/src/screens/SessionChatScreen.tsx#L393-L407

Potential issue: The mobile reconnection logic in `SessionChatScreen.tsx` establishes a
new WebSocket with an `onmessage` handler that is missing handlers for critical message
types, specifically `assistant`, `tool_use`, and `tool_result`. While the main
`connect()` function handles these types correctly, the separate reconnection logic does
not. As a result, when a mobile user returns to the app and the WebSocket reconnects,
they will not see any live streaming assistant responses or tool-related messages, even
though the session continues on the backend. This breaks the core functionality of
receiving real-time updates after a temporary disconnection.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 8368477

@gricha gricha closed this Jan 9, 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