[BUG] Desktop app re-sends initialize + get_workspace_diff to an on-screen Remote Control session every 60 s; the system/init+status flood pushes the conversation past the 2,000-event window the transcript loader reads, so the session opens as "No messages yet"
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Two behaviors combine so that a long-lived Remote Control session opens as "No messages yet" in claude.ai/code and in the Claude desktop app, even though the conversation is intact on disk and on the server.
1. The desktop app re-sends initialize (and get_workspace_diff) to a Remote Control session every 60 seconds while that session is on screen.
Every minute the CLI receives a burst of control_request subtype=initialize (2–3 of them; one request_id is delivered twice) followed by one get_workspace_diff. The CLI answers each initialize with a control_response and emits a fresh system/init and system/status event into the session's server-side event log. That is ~14 events per minute, ~800+ events per hour, per session that is merely being looked at. Nothing is typed; no turn runs.
The polling is tied to the session being visible: it starts the moment the desktop app shows the session and stops as soon as another session is selected. If several remote sessions are visible at once (split panes / pop-outs), all of them are polled. In our logs 8 sessions were polled in lockstep (identical start/stop minutes) for hours — one of them for ~12 hours, until the CLI retired it — because an operator left them open overnight.
A plain browser tab (Chrome 151, claude.ai/code) does not do this: foreground, background (8 min), with the diff panel open, and even after sending a message from the web (that sends initialize x2 + mcp_set_servers once) we observed zero periodic requests. Only the desktop app polls.
2. The transcript loader only looks at the newest 2,000 events and gives up.
When a session is opened, the web bundle (same in the desktop app) fetchesGET /v1/code/sessions/<id>/events?limit=500&sort_order=desc and follows cursor for four pages (2,000 events), then stops and renders only the user/assistant events it found. If the newest 2,000 events are all control_request/control_response/system init/system status noise from (1), the view shows "No messages yet" plus a "Load earlier messages" button; each click loads 500 more. For one of our sessions the conversation only appears after 8 clicks.
So any session that was left on screen in the desktop app for more than ~2.5 hours and then had no further turns looks empty the next time it is opened. Sessions that got a new turn afterwards look fine (the new turn is at the top; the old history is just hidden behind the button), which is why this looks intermittent.
Numbers from one affected session (cse_01VZ9M4nD9nAdUKZRqesT4TY, Opus 5, started with claude --bg --remote-control, CLI 2.1.272):
- 9,081 events on the server, of which 205 are
user/assistant. The last conversation event issequence_num3654. - 5,427 events after the last conversation event: 2,501
control_request(1,869initialize, 627get_workspace_diff, 3mcp_set_servers, 2get_context_usage), 2,501control_response, 1,939system/init, 1,875system/status. initializecadence: bursts of 3 exactly 60 s apart (gap histogram: 1,234 x 0 s, 501 x 60 s), in runs of up to 4.4 hours.get_workspace_diffgaps: 513 x 60 s.- 5 more sessions from the same day have 2,700–5,400 noise events after their last message and all open as "No messages yet".
Regression timeline (same account, same workflow — sessions were always left open in the app):
| Desktop app | initialize per hour on a session left on screen |
|---|---|
| 1.44121.4 (until 2026-09-04) | <= 20 (only when a human actually interacted) |
| 1.46388.1 (installed 2026-09-04 14:03 KST) | 120 (2 per minute) from 2026-09-05 |
| 1.52386.6 (installed 2026-09-14) | 180 (3 per minute) from 2026-09-14 |
Before 2026-09-04, sessions left open all day never accumulated more than a few dozen initialize events, so the 2,000-event loader window was never a problem.
What Should Happen?
- The desktop app should not re-
initializea session on a timer (or, if it needs to refresh permission mode / model / commands, that refresh should not make the CLI appendsystem/init+system/statusevents to the session's persistent event log every time). - The transcript loader should not declare "No messages yet" while older pages exist. It should keep paging until it finds conversation events (or the server could expose the cursor of the last
user/assistantevent so the client can jump there), and control/system chatter should not count toward the window.
Error Messages/Logs
# CLI side (--debug-file) while the desktop app shows the session — repeats every 60 s, nothing typed:
2026-09-14T09:10:38.214Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:10:38.261Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:10:38.496Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:10:38.819Z [DEBUG] [bridge:repl] Inbound control_request subtype=get_workspace_diff
2026-09-14T09:11:38.262Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:11:38.322Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:11:38.550Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:11:38.820Z [DEBUG] [bridge:repl] Inbound control_request subtype=get_workspace_diff
2026-09-14T09:12:38.192Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:12:38.229Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:12:38.447Z [DEBUG] [bridge:repl] Inbound control_request subtype=initialize
2026-09-14T09:12:38.778Z [DEBUG] [bridge:repl] Inbound control_request subtype=get_workspace_diff
# (no "resuming stream deltas" / reconnect lines in between — the subscription stays up; this is a timer, not a reconnect loop)
# Server event log for the same session, newest first (GET /v1/code/sessions/<id>/events?limit=500&sort_order=desc):
# 5,427 consecutive events of these types sit above the first user/assistant event:
# control_request(initialize) -> control_response -> system(init) -> system(status) x 1,869
# control_request(get_workspace_diff) -> control_response x 627
# What the web bundle requests when the session is opened (browser network log), then it stops:
GET https://claude.ai/v1/code/sessions/session_01VZ9M4nD9nAdUKZRqesT4TY/events?limit=500&sort_order=desc
GET https://claude.ai/v1/code/sessions/session_01VZ9M4nD9nAdUKZRqesT4TY/events?limit=500&sort_order=desc&cursor=8883
GET https://claude.ai/v1/code/sessions/session_01VZ9M4nD9nAdUKZRqesT4TY/events?limit=500&sort_order=desc&cursor=8383
GET https://claude.ai/v1/code/sessions/session_01VZ9M4nD9nAdUKZRqesT4TY/events?limit=500&sort_order=desc&cursor=7883
# UI: "No messages yet" + "Load earlier messages" (Korean UI: "아직 메시지가 없습니다" / "이전 메시지 불러오기").
# Each click on the button issues one more page (cursor=7383, ...); the conversation appears after the 8th click.
Steps to Reproduce
- Start a background Remote Control session with a debug log, e.g.
claude --bg --remote-control --name test --debug-file %TEMP%\test.log "Reply with exactly the word: ok"(CLI 2.1.272). - Open that session in the Claude desktop app (Windows, 1.52386.6) and simply leave it on screen. Watch the debug log: every 60 s you get 2–3
Inbound control_request subtype=initializeplus oneget_workspace_diff, andGET /v1/code/sessions/<cse_id>/eventson the server shows a newsystem/init+system/statuspair perinitialize. Select a different session in the sidebar: the polling stops immediately. (Open the same URL in a plain browser instead: nothing is polled.) - Leave the session on screen for ~2.5 hours without sending anything (or open several sessions in split panes to get there faster), so that more than 2,000 events accumulate after the last
user/assistantevent. - Close it, then open the session again from claude.ai/code or the desktop app: the view says "No messages yet" with a "Load earlier messages" button, although the transcript on disk and the server event log both contain the full conversation. Clicking "Load earlier messages" ceil((noise - 2000) / 500) times brings the conversation back.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Desktop app 1.44121.4 (before the 2026-09-04 update to 1.46388.1); the polling is present in 1.46388.1 and 1.52386.6. The CLI side only answers the requests; the timer is in the app.
Claude Code Version
2.1.272 (Claude Code) — standalone CLI hosting the --bg --remote-control sessions; desktop app 1.52386.6 bundles 2.1.270
Platform
Anthropic API (claude.ai account, OAuth)
Operating System
Windows (11 Pro 26200) for both the CLI host and the desktop app
Additional Context
- The affected sessions are long-lived
--bg --remote-controlsessions that a small team opens viahttps://claude.ai/code/session_…links from an internal tool, so they are opened and re-opened over days; that is why the missing history is noticed. Nothing in our tooling talks to the session's control channel — the only clients are the desktop app, claude.ai/code in a browser, and the Android app. - Archiving/re-creating the bridge is not a workaround for us: a fresh bridge has no server-side history at all.