Severity: High — affected sessions are permanently unreadable on web/mobile (paid feature), with no client error indication.
Component: Claude Code Remote Control (claude.ai/code web + Claude iOS app).
First observed: Recurring over multiple days on the same account.
Reproducer: Inconsistent — affects some Remote-Control-enabled sessions but not others. Once a session is affected, it stays broken indefinitely.
Summary
For a subset of Claude Code Remote Control sessions, the cloud has a session header but no events. The web/mobile client correctly fetches /v1/sessions/{id}/events and gets a clean 404 not_found_error, then renders the page with the user's input bubble visible but no assistant content. There is no error banner — the page just silently appears empty.
The local JSONL on disk contains the complete transcript, which is why Claude Code Desktop renders the same session perfectly. The data is intact locally, the session header is intact in the cloud, but the events between them were either never uploaded or were dropped.
Empirical evidence (not speculation)
Confirmed API response from claude.ai
GET https://claude.ai/v1/sessions/session_01JNLd3MFQbJaG5KMcAfqbrA/events?limit=1000
Cookies + headers: replayed from a fresh authenticated browser request
→ HTTP 404
Content-Type: application/json
{
"error": {
"message": "not found",
"type": "not_found_error"
},
"request_id": "req_011CbKeehLJASn9FmCmTxDXd",
"type": "error"
}
The session header endpoint for the same session ID returns 200 with metadata, confirming the orphan state:
GET https://claude.ai/v1/sessions/session_01JNLd3MFQbJaG5KMcAfqbrA
→ 200 (session header present, name "nathans-macbook-pro-local-spicy-newell")
Console error visible in the web client
[REACT_QUERY_CLIENT] QueryClient error: od: Not found
at https://assets-proxy.anthropic.com/claude-ai/v2/assets/v1/c2591c98b-DAE2fHrw.js:0:48593
This is React Query bubbling up the API 404 — the client correctly receives the error, but the UI swallows it and renders nothing instead of showing an error state.
DOM state
document.querySelectorAll('article, [role="article"]').length
// → 0 (no message DOM nodes rendered)
The user's input message is in the DOM because it's stored in the session header / first-page state. Everything after is missing because the events endpoint 404s.
Affected session IDs (account: n*****@***.c, Max plan)
Two examples directly probed during diagnosis:
| Session ID |
Local JSONL |
First user command |
Status |
session_01JNLd3MFQbJaG5KMcAfqbrA |
(created in chrome from /where-are-we-plain) |
/where-are-we-plain |
events 404, header 200 |
session_01GarUV8cJ5RqWwnFFuFSJF7 |
— |
/where-are-we ios-app |
blank on web, full on desktop |
Additional unspecified-ID sessions in the user's sidebar named "iOS app next phase 2", "iOS app next phase 4", etc. — all triggered by the user's personal /build-next-phase ios-app slash command — exhibit the identical symptom. Anthropic logs would show the events-endpoint 404s for these.
Environment
- Claude Code version: 2.1.150
- OS: macOS 15 (Sequoia / Darwin 25.5.0)
- Account plan: Max
- Auth: claude.ai SSO
- Browser tested: Chrome (latest stable)
- iOS app: latest
remoteControlAtStartup: true set globally in ~/.claude/settings.json
Reproduction (best understood)
- Start a Claude Code session from CLI in a project (
cd ~/Projects/foo && claude).
- Remote Control auto-activates due to
remoteControlAtStartup: true — the session header is created on Anthropic's servers, surfaced in the user's sidebar at claude.ai/code.
- First user message is a slash command that immediately performs several tool calls reading project files (e.g.,
/build-next-phase ios-app reads BRIEF/RESEARCH/IMPLEMENTATION/PROGRESS docs at session start).
- Session proceeds normally — the user can chat in the terminal, get responses, do real work.
- When the user opens the session on
claude.ai/code or the iOS app, the transcript area is blank. The session is listed in the sidebar with the correct name, but clicking in shows only an empty page (plus the user's first message bubble).
/v1/sessions/{id}/events returns 404 for the session.
Not 100% reproducible. The same project, same hooks, same skills, same machine, same user can produce healthy sessions alongside broken ones in the same hour. Suggests a race condition rather than a content-dependent bug.
What is NOT the cause (already ruled out, with evidence)
The user's diagnosis path eliminated each of these by direct testing:
- Markdown content (emoji, variation selectors
U+FE0F, ZWJ sequences, tables, blockquotes, HTML <details> tags) — a clone skill with all emoji stripped to ASCII produced the same blank session.
- Initial tool_result size — token-heavy skills like
/last30days render fine on the same account/project; payload size is not the differentiator.
- Skill-specific behavior — fingerprinting record types, attachment types, tool names, MCP tools across 4 broken sessions vs 7 healthy ones in the same project showed zero structural elements unique to the broken set.
- Project configuration —
.claude/settings.local.json is minimal; no project-level hooks; CLAUDE.md is large but other large-CLAUDE.md projects work.
- Renderer/client bug — the React Query client correctly receives and propagates the 404 from the API. The fault is upstream in event persistence, not in rendering.
Workarounds
That do not work:
- Refreshing the page
- Resuming the session in CLI (cloud events don't backfill from local JSONL)
- Clearing browser cache / hard reload
- Reopening on a different device (web, mobile all share the same backend)
- Strip-down clones of the offending skill (verified — clone with all emoji removed still blanks)
That works (single option):
- Use Claude Code Desktop to view affected sessions. Desktop reads the local JSONL, ignoring the cloud entirely. This is the only path to recover the transcript for an already-broken session — and it requires the session to be on the same machine where it was created.
Suspected mechanism (Anthropic engineers can confirm with logs)
The pattern — session header committed, events 404 — is consistent with a race between session creation and the first event upload. The header write succeeds, but the first batch of events either:
- Fails to bind to the newly-created session ID (foreign-key-like dangle), or
- Hits the ingest endpoint before the session is queryable for writes and gets silently dropped, or
- Is uploaded to a different/stale session ID that doesn't match the header
Once the binding is broken, there is no retry path. The events stay in local JSONL only.
Requested action
- Server-side log lookup for
request_id: req_011CbKeehLJASn9FmCmTxDXd and the affected session IDs above. The ingest side should have a trace of either the failed binding or the events going to /dev/null.
- A client-side error state for the empty-events case. Silent blank is the worst possible failure mode. Even "this session has no recorded transcript on the server" would be progress.
- A recovery path — ideally a CLI command like
claude session reupload <local-jsonl> <cloud-id> that pushes the local JSONL events into the cloud session. The data is there on disk; bridging the gap is purely a client capability gap.
- Investigate the race condition. If the first user message is a slash command that fires multiple tool calls in quick succession at session start, the ingest path may be the trigger. Internal repro:
/build-next-phase ios-app style skills that read several docs immediately. Anthropic's QA can repro this on any account by writing a personal skill that does the same.
Diagnostic tool (volunteered)
The user wrote a survey script (cc-session-doctor) that scans local JSONLs, extracts cloud session IDs, and probes /v1/sessions/{id}/events?limit=1 for each. Output is a table of LOCAL-UUID | CLOUD-ID | FIRST-MSG | STATUS where STATUS is HEALTHY | BROKEN (blank on web) | LOCAL-ONLY. Happy to share if useful for the triage team to confirm scope of the issue across this account.
Severity: High — affected sessions are permanently unreadable on web/mobile (paid feature), with no client error indication.
Component: Claude Code Remote Control (claude.ai/code web + Claude iOS app).
First observed: Recurring over multiple days on the same account.
Reproducer: Inconsistent — affects some Remote-Control-enabled sessions but not others. Once a session is affected, it stays broken indefinitely.
Summary
For a subset of Claude Code Remote Control sessions, the cloud has a session header but no events. The web/mobile client correctly fetches
/v1/sessions/{id}/eventsand gets a clean404 not_found_error, then renders the page with the user's input bubble visible but no assistant content. There is no error banner — the page just silently appears empty.The local JSONL on disk contains the complete transcript, which is why Claude Code Desktop renders the same session perfectly. The data is intact locally, the session header is intact in the cloud, but the events between them were either never uploaded or were dropped.
Empirical evidence (not speculation)
Confirmed API response from claude.ai
The session header endpoint for the same session ID returns 200 with metadata, confirming the orphan state:
Console error visible in the web client
This is React Query bubbling up the API 404 — the client correctly receives the error, but the UI swallows it and renders nothing instead of showing an error state.
DOM state
The user's input message is in the DOM because it's stored in the session header / first-page state. Everything after is missing because the events endpoint 404s.
Affected session IDs (account: n*****@***.c, Max plan)
Two examples directly probed during diagnosis:
session_01JNLd3MFQbJaG5KMcAfqbrA/where-are-we-plain)/where-are-we-plainsession_01GarUV8cJ5RqWwnFFuFSJF7/where-are-we ios-appAdditional unspecified-ID sessions in the user's sidebar named "iOS app next phase 2", "iOS app next phase 4", etc. — all triggered by the user's personal
/build-next-phase ios-appslash command — exhibit the identical symptom. Anthropic logs would show the events-endpoint 404s for these.Environment
remoteControlAtStartup: trueset globally in~/.claude/settings.jsonReproduction (best understood)
cd ~/Projects/foo && claude).remoteControlAtStartup: true— the session header is created on Anthropic's servers, surfaced in the user's sidebar at claude.ai/code./build-next-phase ios-appreads BRIEF/RESEARCH/IMPLEMENTATION/PROGRESS docs at session start).claude.ai/codeor the iOS app, the transcript area is blank. The session is listed in the sidebar with the correct name, but clicking in shows only an empty page (plus the user's first message bubble)./v1/sessions/{id}/eventsreturns 404 for the session.Not 100% reproducible. The same project, same hooks, same skills, same machine, same user can produce healthy sessions alongside broken ones in the same hour. Suggests a race condition rather than a content-dependent bug.
What is NOT the cause (already ruled out, with evidence)
The user's diagnosis path eliminated each of these by direct testing:
U+FE0F, ZWJ sequences, tables, blockquotes, HTML<details>tags) — a clone skill with all emoji stripped to ASCII produced the same blank session./last30daysrender fine on the same account/project; payload size is not the differentiator..claude/settings.local.jsonis minimal; no project-level hooks; CLAUDE.md is large but other large-CLAUDE.md projects work.Workarounds
That do not work:
That works (single option):
Suspected mechanism (Anthropic engineers can confirm with logs)
The pattern — session header committed, events 404 — is consistent with a race between session creation and the first event upload. The header write succeeds, but the first batch of events either:
Once the binding is broken, there is no retry path. The events stay in local JSONL only.
Requested action
request_id: req_011CbKeehLJASn9FmCmTxDXdand the affected session IDs above. The ingest side should have a trace of either the failed binding or the events going to /dev/null.claude session reupload <local-jsonl> <cloud-id>that pushes the local JSONL events into the cloud session. The data is there on disk; bridging the gap is purely a client capability gap./build-next-phase ios-appstyle skills that read several docs immediately. Anthropic's QA can repro this on any account by writing a personal skill that does the same.Diagnostic tool (volunteered)
The user wrote a survey script (
cc-session-doctor) that scans local JSONLs, extracts cloud session IDs, and probes/v1/sessions/{id}/events?limit=1for each. Output is a table ofLOCAL-UUID | CLOUD-ID | FIRST-MSG | STATUSwhere STATUS isHEALTHY | BROKEN (blank on web) | LOCAL-ONLY. Happy to share if useful for the triage team to confirm scope of the issue across this account.