[BUG] Desktop app: after auto-update stealth-relaunch, the conversation view rewinds — navigation history is saved with a stale `active` index

Status Fixed / completed
Reported on v2.1.229
Maintainer reply None cached
Activity 4 comments · opened Aug 18, 2026 · closed Aug 25, 2026

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?

Every time the macOS desktop app auto-updates, it performs a "stealth relaunch" and restores the previous navigation state. The restore lands on an older navigation entry, so the visible conversation rewinds by dozens of messages and never catches up. It always rewinds to the same point.

The transcript on disk is fine and the underlying CLI session keeps working — only the rendered view is rewound. The model still has full context and the JSONL under ~/.claude/projects/ keeps growing normally. Reopening the same session from a terminal with claude -r <session-id> renders the full history correctly, which confirms the data is intact and the defect is in the save/restore path of the navigation state.

The logs show the app saves the navigation history already pointing at a stale index (active=1 out of 3 entries), so the bug appears to be on the save side rather than the restore side.

There is no notice that a relaunch happened, so it looks like data loss from the user's point of view.

What Should Happen?

After a stealth relaunch, the app should restore the most recent navigation entry and re-render the conversation up to the latest message.

If a relaunch happens while the user is mid-conversation, it would also help to show a brief notice that the app restarted for an update.

Error Messages/Logs

From ~/Library/Logs/Claude/main.log (2026-08-18):

15:45:50 [info] [updater] Update downloaded and ready to install { releaseName: 'Claude 1.32352.1' }
15:55:50 [info] [stealth-relaunch] otherAppFullScreen=false
15:55:50 [info] [stealth-relaunch] Saved navigation history (3 entries, active=1)
15:55:50 [info] beforeQuitForUpdate handler fired, going down for update
15:55:58 [info] [CCD] Initialized with version 2.1.229
15:55:58 [info] [updater] Version changed since last launch: 1.32352.0 -> 1.32352.1
15:55:58 [info] [stealth-relaunch] Detected via marker file (windowVisible=true, windowMinimized=false, otherAppFullScreen=false)
15:55:58 [info] [stealth-relaunch] Loaded navigation history (3 entries, active=1)
15:55:58 [info] [stealth-relaunch] Restoring navigation (3 entries, active=1)

An earlier occurrence the same day saved "(4 entries, active=3)" and also rewound the view.

After the relaunch a fresh internal session is mapped onto the existing CLI session, and the CLI session continues normally while the rendered list stays rewound:

[info] Mapping internal session local_<uuid> to CLI session <cli-session-uuid>

If a tool-permission prompt is open at the moment of the relaunch, it dies with:

Tool permission request failed: AbortError: Tool permission stream closed before response received

Steps to Reproduce

  1. Open a long conversation in the macOS desktop app and keep working in it.

(Mine was ~900 JSONL lines / 5.1 MB, including several pasted screenshots.)

  1. Wait for an auto-update to be downloaded and applied. In the log this appears as

"[updater] Update downloaded and ready to install" followed by
"beforeQuitForUpdate handler fired, going down for update".

  1. The app quits and relaunches itself silently (stealth relaunch).
  2. Look at the conversation: the rendered message list has rewound by dozens of

messages, always to the same point. New messages still work, but everything
between that point and the latest message is gone from the view.

  1. Check ~/.claude/projects/<project>/<session-id>.jsonl — the transcript is complete

and still growing, so nothing was actually lost on disk.

Reproduced on every auto-update: 5 out of 5 over six days on this machine.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.229 (Claude Code, bundled in desktop app 1.32352.1)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

This is about the macOS desktop app, not a terminal session. The Terminal/Shell field
above is filled in only because it is required.

Frequency — five updates in six days on this machine, and the rewind occurred on all
five. "[stealth-relaunch] Restoring navigation" appears exactly 5 times in main.log:

2026-08-12 10:41 1.26832.0 -> 1.28929.0
2026-08-14 08:52 1.28929.0 -> 1.30096.1
2026-08-15 12:55 1.30096.1 -> 1.30096.5
2026-08-18 09:50 1.30096.5 -> 1.32352.0
2026-08-18 15:55 1.32352.0 -> 1.32352.1

Impact:

  • The visible conversation silently rewinds while work is in progress, with no notice

that a relaunch happened.

  • An open tool-permission prompt dies with an AbortError at the same moment.
  • Users reasonably assume the conversation was lost. In my case the data was intact,

but confirming that required digging through main.log and the JSONL transcript.

Environment:

  • Claude desktop app 1.32352.1 (also seen on 1.32352.0, 1.30096.5, 1.30096.1, 1.28929.0)
  • Claude Code 2.1.229 (bundled in the desktop app). The CLI on PATH reports 2.1.161.
  • macOS 26.5 (25F71), Apple Silicon, 32 GB RAM

Possibly related, but not the same report:

  • #64887 — Desktop loses active session when app relaunches for update
  • #69456 — Offer to resume interrupted runs after a relaunch/update
  • #53091 — Scrollback not rehydrated after restart (VS Code extension)

Those describe adjacent symptoms; this report adds the specific stealth-relaunch
navigation-index evidence.

View original on GitHub ↗

4 Comments

getskishi · 12 days ago
[!WARNING] The version attribution in this comment is withdrawn. See the correction below: the fallback point predates the update, so I no longer have evidence that 1.32352.0 introduced this. The observations about the symptom itself still stand.

---

Update: this is a regression in 1.32352.0, and it is worse than first reported

After several more restarts today I can narrow this down considerably. Correcting my original report: the rewind is not limited to the stealth-relaunch path, and it is not pre-existing behaviour.

It started with 1.32352.0

Every restart on 1.32352.x lost conversation view state. No restart before that did — I had been updating and restarting normally for weeks without ever losing a conversation.

2026-08-18 08:53  start   1.30096.5     fine
2026-08-18 09:50  update  -> 1.32352.0  view lost from this point on
2026-08-18 10:45  start   1.32352.0     lost again
2026-08-18 15:55  update  -> 1.32352.1  lost again
2026-08-18 17:33  start   1.32352.1     lost again (manual restart)

Earlier update-restarts on this machine (1.26832.0 -> 1.28929.0 on 08-12, -> 1.30096.1 on 08-14, -> 1.30096.5 on 08-15) did not lose anything. 4/4 reproduction on 1.32352.x, 0/3 before it.

Exact symptom

One long session was open across the 1.32352.0 update. Since then:

  • Messages up to a fixed point (roughly where the app updated) still render after every restart.
  • Everything after that point disappears from the view on every restart, always returning to the same place.
  • The session still works — new messages send and render fine, and the model retains full context.
  • Switching to another session and back loses nothing further, but does not recover what disappeared.

The data is intact; only the view is affected

  • The CLI transcript is complete and valid: 1,702 lines, 7.1 MB, every line parses as JSON, no truncation.
  • claude -r <session-id> from a terminal renders the full history correctly.
  • Session size is not a factor: 24 of my 46 sessions are larger than this one (largest is 105 MB) and they are unaffected.

Other sessions are fine, which narrows it down

Opening any pre-update session from the sidebar renders its full history normally on 1.32352.1. So the load-from-disk path works. It appears not to run for the session that was live across the restart: the app keeps the same internal session id across restarts (Mapping internal session local_<uuid> to CLI session <cli-uuid> with an unchanged local_ id since before the restart), so that session seems to be treated as already loaded while its in-memory messages are gone.

Manual restart vs stealth relaunch

The two paths differ, and the manual one is worse:

  • Update relaunch logs [stealth-relaunch] Saved navigation history (N entries, active=M) and Restoring navigation, and lands on a stale entry.
  • A user-initiated quit and reopen logs no stealth-relaunch lines at all, so nothing is restored.

Ruled out

  • Disk layout: all Claude paths (~/.claude, ~/Library/Application Support/Claude, ~/Library/Logs/Claude, /Applications/Claude.app) are real directories on the internal volume, no symlinks.
  • Session size (see above).
  • Transcript corruption (see above).
  • The per-session file under Application Support/Claude/claude-code-sessions/.../local_<uuid>.json holds metadata only (281 KB, no message content), so it is not a truncated message store.

Environment

  • Claude desktop 1.32352.1 (regression introduced in 1.32352.0; 1.30096.5 was fine)
  • Claude Code 2.1.229
  • macOS 26.5 (25F71), Apple Silicon, 32 GB RAM
getskishi · 12 days ago

Correction: withdrawing the "regression in 1.32352.0" claim

My previous comment asserted this was introduced in 1.32352.0. I no longer have the evidence to support that, so I am withdrawing it. Sorry for the noise — please disregard the version attribution while triaging.

Why I withdrew it

I located the exact point the view falls back to. It is line 219 of a 1,702-line transcript, timestamped 2026-08-17T08:39:28Z — the day before the update to 1.32352.0.

2026-08-17 17:11 JST  session created (app on 1.30096.5)
2026-08-17 17:39 JST  <- the view never shows anything past this point
2026-08-17 20:09 JST  app quit
2026-08-18 08:53 JST  app start (still 1.30096.5)
2026-08-18 09:50 JST  update -> 1.32352.0

There is no restart, quit, or update at 17:39 on 08-17. So the cut-off does not line up with the version change, and the persisted view state may already have stopped advancing while the app was still on 1.30096.5. I had inferred the regression from the fact that I first noticed the loss right after the update; that is not the same as it starting there.

I could not determine the mechanism. The cut-off is at 1.52 MB / 219 lines into the transcript, which does not match any obvious cap.

What is still established

These are direct observations and I am confident in them:

  • The transcript is intact. 1,702 lines, 7.1 MB, every line parses as JSON. claude -r <session-id> from a terminal renders the full history correctly. Only the in-app view is affected.
  • The affected session always falls back to the same point on every restart — both update relaunches and user-initiated quit/reopen. New messages send and render fine, and the model retains full context; only the scrollback above the cut-off is missing.
  • Newly created sessions are not affected. I created two new sessions after the update, restarted the app, and both retained their content in full.
  • Pre-existing sessions are not affected. Opening any other session from the sidebar renders its full history normally, so the load-from-disk path works.
  • Session size is not the factor. 24 of my 46 sessions are larger than the affected one (largest 105 MB) and are fine.
  • Not a disk-layout issue. All Claude paths are real directories on the internal volume, no symlinks.
  • The per-session file under Application Support/Claude/claude-code-sessions/.../local_<uuid>.json is metadata only (281 KB, no message content), so it is not a truncated message store.

Manual restart vs stealth relaunch

Still worth noting, since the two paths behave differently:

  • An update relaunch logs [stealth-relaunch] Saved navigation history (N entries, active=M) followed by Restoring navigation.
  • A user-initiated quit and reopen logs no stealth-relaunch lines at all.

Across restarts the app keeps the same internal session id (Mapping internal session local_<uuid> to CLI session <cli-uuid> with an unchanged local_ id), which may be why the affected session is never re-read from disk while other sessions are.

Environment

  • Claude desktop 1.32352.1 (the session was created on 1.30096.5 and spanned the update)
  • Claude Code 2.1.229
  • macOS 26.5 (25F71), Apple Silicon, 32 GB RAM
UzanRuben · 12 days ago

I hit the same fallback on my main conversation and assumed it had either reached some
invisible limit or gotten corrupted, so 4 days ago I created a fresh one and moved my
work there. That new session has now done exactly the same thing: this morning, after
an app update, the rendered view fell back to a message from 3 days ago, even though I
was still working in it right before the update.

If your two test sessions haven't been through an update yet, they may not be a
negative result so much as a test still pending — worth re-checking them after the
next one.

Same signature as yours: the model still recalls the messages above the cut-off when I
ask it explicitly, new messages send and render fine, only the scrollback is gone. So
on this machine it has happened to two independent sessions, one of them created from
scratch.

Environment: Claude 1.32352.1 (6c6aa5) / MacOS Golden Gate 27.0 Developer Beta 6 / Apple M1 Pro

getskishi · 12 days ago

I found the root cause on my machine. It is not the auto-update — it is a Unicode normalization mismatch that splits one working directory into two different project keys under ~/.claude/projects/.

Root cause

~/.claude/projects/ derives a directory key from the cwd by replacing every non-alphanumeric character with -. On my machine the same folder produces two keys, because the path is normalized differently depending on the code path:

A (NFC): -Users-kishi--------getskishi-gmail-com-------------      mode 755  <- written to (live)
B (NFD): -Users-kishi--------getskishi-gmail-com---------------    mode 700  <- what the view falls back to

My cwd is /Users/kishi/マイドライブ(getskishi@gmail.com)/ゲッツ!!業務フォルダ. The two extra dashes come from the last path segment: decomposes to + and to + under NFD, so two characters become four. Note that only the last segment differs — the parent segment is NFC in both keys (pure NFD would have widened it too), so the two keys are produced by different normalization of different parts of the path.

Each session exists as a JSONL file in both directories. The copy in B stops being appended to shortly after the session starts; A keeps growing.

Evidence

The fallback point matches B's last write exactly, for both sessions:

| session | A (live) | B (stale) |
|---|---|---|
| 2ee53120-… | 1,817 lines, last write 2026-08-18 18:08 | 220 lines, last write 2026-08-17 17:39:28 |
| 01e50348-… | 71 lines, last write 2026-08-19 08:47 | 11 lines, last write 2026-08-18 17:57:35 |

The first session always falls back to 17:39. The second always falls back to its first exchange at 17:57. Both are exactly where the B copy stops.

This also explains the rest of the signature: the data is never lost (A is intact), claude -r <session-id> shows everything, the model still recalls messages above the cut-off, and new messages send and render fine.

Confirmed by intervention. I replaced the two stale files in B with symlinks to their counterparts in A, restarted, and the full scrollback came back in both sessions. So the renderer is definitely reading the B key while the writer appends to the A key.

Corrections to earlier hypotheses in this thread

  • It is not the auto-update. I reproduced it with a manual restart while v1.32885.1 was still sitting un-applied in the "Restart to update" button. A plain relaunch — i.e. re-reading the session — is sufficient.
  • It is not limited to old sessions. @UzanRuben was right that an un-updated session is a pending test rather than a negative result. My freshly created session broke on its first restart.
  • It is not version-related. Earlier versions on my machine behaved the same.

Trigger condition

Paths containing characters that differ between NFC and NFD — for me, Japanese folder names with dakuten/handakuten. On the same machine:

| path | duplicated? |
|---|---|
| …/ゲッツ!!業務フォルダ | yes (A 1,903 lines / B 231 lines) |
| …/ゲッツ!!業務フォルダ/GETS-WEB | yes (A 9,410 lines / B 9,036 lines) |
| ~/app_development/… (ASCII) | no |
| ~/Documents/… (ASCII) | no |

All 45 of my other sessions, all under ASCII paths, are unaffected. This probably explains why the report count is low: it needs a non-ASCII cwd with decomposable characters.

Detection

cd ~/.claude/projects && python3 -c "
import os,glob
from collections import defaultdict
b=os.path.expanduser('~/.claude/projects/')
g=defaultdict(list)
for d in os.listdir(b):
    if os.path.isdir(b+d): g[d.replace('-','')].append(d)
for k,v in g.items():
    if len(v)>1:
        for d in sorted(v,key=len):
            n=sum(sum(1 for _ in open(f,errors='replace')) for f in glob.glob(b+d+'/*.jsonl'))
            print(f'{len(d):3d} {oct(os.stat(b+d).st_mode)[-3:]} {n:6d} lines {d}')
"

Any pair printed under one group is the same folder split in two.

One more thing worth checking on the fix

In one of my two duplicated projects, the B side holds two sessions that do not exist in A at all (1,389 and 1,173 lines). So the split is not always "live copy plus stale shadow" — some conversations may live only under the key that is currently not being written to. A fix that simply prefers one key will need to merge rather than discard.

Suggested fix

Normalize the path to a single form (NFC) before deriving the project key, and on startup merge any existing keys that are normalization variants of each other.

Environment: macOS 26.5 (build 25F71, Darwin 25.5.0) / Apple Silicon / cwd on Google Drive.