Skip to content

fix: clear claudeStatus and resync writer on WebSocket reconnect#570

Open
netrezver wants to merge 1 commit intositeboon:mainfrom
netrezver:fix/ws-reconnect-thinking-indicator
Open

fix: clear claudeStatus and resync writer on WebSocket reconnect#570
netrezver wants to merge 1 commit intositeboon:mainfrom
netrezver:fix/ws-reconnect-thinking-indicator

Conversation

@netrezver
Copy link
Copy Markdown

@netrezver netrezver commented Mar 22, 2026

Problem

The thinking/processing indicator sometimes stays stuck after the response is complete. The user has to click Stop Generation to dismiss it.

Root Cause

handleWebSocketReconnect in src/components/chat/view/ChatInterface.tsx has two bugs:

1. Missing setClaudeStatus(null)

When a message is sent, setClaudeStatus({ text: 'Processing', ... }) is called. On WebSocket reconnect, handleWebSocketReconnect calls setIsLoading(false) but never clears claudeStatus. Since ClaudeStatus renders whenever isLoading || status is truthy, the indicator stays visible indefinitely with a stale status.

2. No check-session-status on reconnect

WebSocketWriter.send() silently drops messages when readyState !== OPEN:

send(data) {
    if (this.ws.readyState === 1) {
        this.ws.send(JSON.stringify(data));
    }
    // silent drop otherwise
}

If the connection drops after the last message but before complete is delivered, complete is lost. On reconnect, handleWebSocketReconnect does not send check-session-status, so the server never calls reconnectSessionWriter — the writer stays bound to the dead WebSocket and complete keeps getting dropped on any retry.

Fix

Send check-session-status on reconnect so the server rebinds the writer to the new WebSocket, and clear claudeStatus so no stale status persists.

   const handleWebSocketReconnect = useCallback(async () => {
     if (!selectedProject || !selectedSession) return;
     const providerVal = (localStorage.getItem('selected-provider') as SessionProvider) || 'claude';
     await sessionStore.refreshFromServer(selectedSession.id, {
       provider: (selectedSession.__provider || providerVal) as SessionProvider,
       projectName: selectedProject.name,
       projectPath: selectedProject.fullPath || selectedProject.path || '',
     });
     setIsLoading(false);
     setCanAbortSession(false);
+    setClaudeStatus(null);
+    if (sendMessage) {
+      sendMessage({ type: 'check-session-status', sessionId: selectedSession.id, provider: providerVal });
+    }
-  }, [selectedProject, selectedSession, sessionStore, setIsLoading, setCanAbortSession]);
+  }, [selectedProject, selectedSession, sessionStore, setIsLoading, setCanAbortSession, setClaudeStatus, sendMessage]);

Summary by CodeRabbit

  • Bug Fixes
    • Improved chat session reconnection to prevent stale connections from receiving outdated messages, ensuring reliable message delivery when the chat service reconnects.

handleWebSocketReconnect was missing two things:
1. setClaudeStatus(null) — stale "Processing" status persisted after
   reconnect, keeping the thinking indicator visible indefinitely
2. check-session-status — without it, the server writer stays bound to
   the dead WebSocket; the `complete` event is then silently dropped
   (WebSocketWriter.send is a no-op when readyState != OPEN), leaving
   isLoading stuck at true

Fix: clear claudeStatus and send check-session-status on reconnect so
the server rebinds the writer and the indicator clears correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3fbbf00d-a30d-4c81-97ca-45168104efda

📥 Commits

Reviewing files that changed from the base of the PR and between 42a1313 and 72e04aa.

📒 Files selected for processing (1)
  • src/components/chat/view/ChatInterface.tsx

📝 Walkthrough

Walkthrough

This change modifies the WebSocket reconnect handler to clear claudeStatus and send a check-session-status message containing the current sessionId and provider, triggering server-side writer reconnection to the newly established WebSocket and preventing events from being delivered to stale connections.

Changes

Cohort / File(s) Summary
WebSocket Reconnect Handler
src/components/chat/view/ChatInterface.tsx
Enhanced reconnect handler to clear claudeStatus, dispatch check-session-status message with sessionId and provider, and trigger server-side writer reconnection to prevent event delivery to stale connections.

Possibly related PRs

Suggested reviewers

  • blackmammoth
  • viper151

Poem

🐰 A hop, a skip, a socket's bind,
When WebSocket winks and leaves behind,
We clear the status, send the call,
"Writer, reconnect!"—and that's all! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: clear claudeStatus and resync writer on WebSocket reconnect' accurately and concisely describes the main changes in the pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can validate your CodeRabbit configuration file in your editor.

If your editor has YAML language server, you can enable auto-completion and validation by adding # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json at the top of your CodeRabbit configuration file.

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