[BUG] Rewind+continue (fork) makes all prior conversation disappear from the rendered transcript in local-agent-mode (Cowork) sessions

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 31, 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?

Summary

In a long Claude Desktop local-agent-mode / Cowork session, after Rewinding to an earlier message and continuing, the chat UI stops rendering everything before a certain node. The early conversation is no longer visible, even when scrolling. This is a display-layer (transcript stitching) bug — the data is fully intact on disk; only the rendered thread is truncated.

Environment

  • Product: Claude Desktop app, the Cowork / local-agent-mode feature.
  • Renderer: bundled in app.asar (index.chunk-*.js). Not user-editable.
  • Session storage: <base>\local-agent-mode-sessions\<workspace>\<group>\local_<sessionId>\
  • The rendered conversation is surfaced from the Claude Code runtime transcript (.jsonl) that the app resolves via cliSessionId.

What Should Happen?

Symptom / expected vs actual

Expected: The full conversation history (all turns, including earlier nodes) renders continuously.

Actual: Only the tail of the conversation renders. Everything before a mid-conversation node is gone from the UI. The user correctly identified it as a local rendering/stitching issue (not model-context compaction), and confirmed the data was not lost — only the rendered thread was truncated.

Error Messages/Logs

## Root cause

A session holds a single active Claude Code run identified by **`cliSessionId`** in its sidecar metadata file (`local_<sessionId>.json`). When the user **rewinds** to an earlier message and then continues, the app:

1. Keeps the existing (pre-rewind) run's transcript untouched,
2. Auto-creates a **new continuation run** (logged as `forkSession=true`) to carry the new turns.

The new continuation run's transcript **starts at the last `compact_boundary`** ("This session is being continued from a previous conversation") — i.e. it only contains the tail. Because the app renders **only** the transcript for `cliSessionId`, the pre-rewind run's content (which holds the early history) is never stitched in, so it disappears from the UI.

There is **no user-facing "fork" button**; the fork is an internal side effect of rewind + continue.

## Evidence (from an affected session)

Two Claude Code runs exist for the same session:

| Run | Role | Content | Size |
|-----|------|---------|------|
| Run A | pre-rewind | Messages 1–17 (full early history, spanning several days) | ~22 MB / ~1600 lines |
| Run B | current (`cliSessionId`) | Starts at a mid-session `compact_boundary`; messages ~14–22 | ~0.6 MB |

- App log: `[Rewind] Rewinding session ... to message <messageAnchor>-...` then `[Rewind] resumeSessionAt=... + forkSession=true`.
- Before rewind the app logged `Loaded 1279 messages from transcript` (≈ Run A's count).
- Audit event `command_lifecycle` shows Run B being created at the same moment as the rewind (timestamps line up after timezone conversion).
- Of 22 top-level user turns in the session, Run B contains only the later ones; the early turns exist **only** in Run A.
- Transcript lines carry a `sessionId` field; the app reads the `cliSessionId` run's transcript.
- The doubled `[tool_result]` side-channel lines (once live, once compacted replay) are a normal Claude Code transcript pattern, unrelated to this bug.

Steps to Reproduce

Reproduction steps

  1. Have one long local-agent-mode (Cowork) session that has undergone a few automatic compactions (compact_boundary).
  2. Rewind to an earlier message (one that is after some compaction boundary, or generally earlier in the thread) and then continue sending in that thread. The app creates a new continuation run that starts at the last compact boundary.
  3. Reopen / scroll the session. The messages before the new run's starting point no longer render.

Proposed fix

When resuming a forked continuation run, the renderer should also load and stitch the ancestor run(s) up to the fork point, so the rendered transcript is continuous. Concretely:

  • Resolve the full history by walking the run's parent_uuid / logicalParentUuid lineage rather than rendering only the current run; or
  • On rewind + continue, keep reading the ancestor transcript up to the rewind anchor and append the new fork content.

Claude Model

Other

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

Version 1.40609.0 (f65e38)

Platform

Other

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Workaround (local data repair, non-destructive)

For a single affected session, merge the two runs into the current run's .jsonl:

  1. Take Run A's full content + Run B's net-new lines (dedup by messageId / uuid).
  2. Normalize every line's sessionId to the cliSessionId.
  3. Write into the current run's transcript file; fully quit and reopen the app (the session was cached live in memory — log: [Restore] Skipping ... live session already in memory), otherwise the app's in-memory write-back will clobber the merge.
  4. Back up all originals first.

This confirmed the data was never lost — only not stitched into the rendered thread.

View original on GitHub ↗