Expose session id lineage (transcript path and prior ids from resume/fork) so multi-session workflows can resolve stale ids

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 25, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

In heavy multi-session use, session identity fragments across namespaces and there is no supported way to map between them, so cross-session messages get addressed to ids that no longer route.

Measured in one project directory: 139 transcript files under ~/.claude/projects are really 114 distinct sessions. After a resume or fork, the head lines of the new transcript retain the PRIOR session's sessionId, so peers, docs and notes keep circulating ancestor ids. Union-finding every id that co-occurs in a file yields 15 lineage chains dragging 24 dead alias ids (one chain has 7). Separately, some local_<uuid> ids returned by list_sessions match no transcript filename anywhere on disk, while list_events can still read those sessions' transcripts, so the mapping clearly exists internally but is not exposed.

Consequences in practice: cross-session messages delivered to a dead ancestor's inbox and found unread days later; two sessions displaying identical titles after a resume chain, making title-based resolution a coin flip; and session archaeology (locating a transcript from the id the app reports) failing outright. The human ends up hand-routing messages between their own sessions.

Proposed Solution

Add lineage/identity fields to get_session (and optionally list_sessions):

  • transcriptPath: absolute path to the session's current transcript file
  • aliasIds: prior session ids this session has been known by (resume/fork ancestry)
  • canonicalId: a stable id that survives resume/fork, if one exists internally

That alone would let any multi-session workflow resolve "old id -> current session" before addressing anything, instead of guessing. It pairs with #89378 (tools should error rather than silently fall back on unresolvable ids): together they make stale ids fail safe AND become fixable.

Alternatives considered: a resolve_session(any_known_id) endpoint without full lineage; or keeping one durable id across resume/fork so aliases never accumulate (cleanest, biggest change). What I had to build instead: scan ~/.claude/projects/*/*.jsonl, read head and tail sessionId per file, union-find co-occurring ids, treat the newest file per component as live. That covers the transcript namespace only, cannot join the local_<uuid> namespace at all, and depends on undocumented file layout.

Alternative Solutions

Alternative A: a resolver endpoint, e.g. resolve_session(any_known_id) -> current session, without exposing full lineage.

Alternative B: keep one durable session id across resume/fork so aliases never accumulate. Cleanest long term, likely the biggest change.

Alternative C (what I had to build): scan ~/.claude/projects/*/*.jsonl, read head and tail sessionId from each file, union-find all ids that co-occur, and treat the newest file in each component as the live session. This works for the transcript namespace but cannot join the local_<uuid> namespace at all, and it depends on undocumented file layout that could change at any release.

Priority

Critical - Blocking my work

Feature Category

CLI commands and flags

Use Case Example

A repo with ~20 concurrent sessions coordinating work, each writing to a per-session inbox file keyed by session id, plus direct cross-session messages.

Today: session A resumes, gets a new transcript filename, and every peer that recorded A's old id keeps writing to a file nothing reads. Three multi-page reports sat unread in an ancestor's inbox for two days, found only by manually diffing inbox files. A separate lane wasted a turn sending to two different ids for the same session, both of which bounced.

With aliasIds / transcriptPath exposed: a lane resolves the target id once before sending, hits the live session, and nothing needs manual recovery.

Environment: Claude desktop app 1.34493.1, macOS (Darwin 24.6.0). Filed separately from the bug in #89378 per the single-issue rule; they are two halves of one problem. Happy to share the union-find measurement script.

Additional Context

Environment: Claude desktop app 1.34493.1, macOS (Darwin 24.6.0), session-management MCP tools.

Filed as a feature request separately from the bug in #89378 per the single-issue rule; they are the two halves of the same problem (fail safe on stale ids, and make stale ids resolvable). Happy to share the union-find measurement script if useful.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗