Session title diverges between Desktop app and mobile/web — two independent title stores that never reconcile

Resolved 💬 4 comments Opened May 31, 2026 by AviHack Closed Jul 15, 2026

Preflight Checklist

  • [x] I have searched existing issues. Closest are #36164 (recents show last message), #32150 / #49712 / #63127 (auto-title overwrites custom title), #63765 (VS Code rename not persisting), and #48868 (docs: claude.ai→CLI rename). None describes this two-store desktop↔mobile divergence or its mechanism.
  • [x] This is a single bug report.
  • [x] I am using the latest version of Claude Code (v2.1.156).

What's Wrong?

The same Claude Code session shows two different titles depending on the surface you view it from:

  • Desktop app sidebar → a clean, AI-generated title (e.g. Email formatting and presentation).
  • iOS Code tab / claude.ai web → the first user message instead (e.g. what do you suggest we do?), or — if you ever interrupted a turn — a junk artifact like session interrupted by user.

Root cause (verified on disk on Windows): the Desktop app keeps two independent title stores for the same session and never reconciles them:

  1. Native Code-tab store%APPDATA%\Roaming\Claude\claude-code-sessions\<ws>\<x>\local_<id>.jsontitle. This is the app's own aiTitle, and it's what the desktop sidebar renders. (File is keyed by the desktop's own session id; the CLI id is in cliSessionId, and bridgeSessionIds links to the cloud session.)
  2. Cloud Bridge store — the embedded claude.ai cache at %APPDATA%\Roaming\Claude\IndexedDB\https_claude.ai_* (record kind:"bridge", tag:"remote-control-sdk", keyed by the bridge session id) → title. This is what iOS and claude.ai/code render.

The local CLI transcript (~/.claude/projects/.../<id>.jsonl) and .claude.json contain no session title field at all (.claude.json only caches lastSessionFirstPrompt), so neither title is shared through those.

Because the two stores generate titles independently and never sync, the surfaces disagree by default. Which surface you rename from then determines what happens:

| Action | Native store (desktop) | Cloud Bridge (mobile/web) | Result |
|---|---|---|---|
| No explicit rename | auto aiTitle | first / last message (or interrupt marker) | diverges |
| Rename from iOS / claude.ai | unchanged | updated | diverges further |
| Rename via Desktop app's Rename button | updated | updated | unified ✅ |
| /rename slash command in the Desktop Code tab | "not available in this environment" | — | no-op |
| /rename slash command from iOS | unchanged | unchanged | no-op |

So the only action that makes all three surfaces agree is the desktop Rename button, which writes both stores. An iOS/web rename only ever updates the cloud side.

Steps to Reproduce

  1. Enable Remote Control by default (Desktop: Settings → Claude Code → Enable remote control by default).
  2. Start a session in the Desktop app and send a few messages, but do not rename it.
  3. Observe the desktop sidebar title — a meaningful AI-generated title.
  4. Open the same session in the iOS app's Code tab (or claude.ai/code). It shows the first user message instead of that title.
  5. Rename it from iOS → only the mobile/web title changes; the desktop sidebar keeps its old title.
  6. Rename it via the Desktop app's Rename button → both finally match.

Expected Behavior

A single canonical title per session, consistent across desktop, web, and mobile. At minimum, the desktop's auto-generated aiTitle should propagate to the cloud Bridge session the same way a desktop rename does — so the mobile/web Code list doesn't fall back to the raw first message.

Additional Notes

  • The cloud Bridge title also latches onto interrupt markers: after interrupting a turn, the mobile/web title became session interrupted by user and never refreshed. (Possibly related to the earlier "/resume showing interrupt messages as session titles" fix, but on the Remote Control / cloud path.)
  • Environment: Claude Code Desktop app, v2.1.156, Windows 11. Remote Control enabled at startup.

View original on GitHub ↗

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