Skip to content

fix(#283): auto-heal panes stuck at 'loading transcript' on startup/resume - #297

Closed
Juliusolsson05 wants to merge 1 commit into
mainfrom
fix/283-autoheal-stuck-transcripts
Closed

Juliusolsson05 wants to merge 1 commit into
mainfrom
fix/283-autoheal-stuck-transcripts

Conversation

@Juliusolsson05

Copy link
Copy Markdown
Owner

The bug (plain version)

On startup/resume, the saved-transcript channel sometimes fails to attach to a pane while the live channel works fine. The pane then either spins forever on "loading transcript" or paints an empty "waiting for Claude" feed with the user's prompts missing — until a manual reload fixes it. Confirmed from feed-debug: one restored pane logged 22 MB of live activity but rendered a single "waiting for Claude" row.

Two underlying causes (both from the #284 instrumentation + rehydrate analysis):

  1. Dropped write — the load's terminal ready/error write is discarded when its runtime key is dropped/re-keyed mid-flight (RESOLVE-DROPPED / ERROR-DROPPED).
  2. Marked-but-never-loaded — rehydrate marks a pane loading but the loader is never kicked.

Either way: pane stuck at loading with nothing driving it. A manual reload re-runs the loader under a now-stable id and fixes it.

The fix

Automate that manual reload:

  • Track in-flight loads in a module Set (added before the loading write, cleared in a finally on every exit including the dropped-write paths).
  • reconcileStuckTranscriptLoads() — sweep current runtimes for panes that are (a) stuck loading, (b) not currently loading, (c) backed by a durable provider session, and re-drive the load for each. Conservative: only touches already-broken panes, no-op otherwise.
  • useBootstrap schedules three detached sweeps (1.5s / 4s / 8s after rehydrate) so a slow first load settles before a pane is judged stuck, and panes that only go stuck after their dropped load resolves still get caught.

Covers both failure modes. Renderer-only, typechecks clean.

⚠️ Needs a live test before merge (startup-critical)

Run the app, restart it with several Claude/Codex panes open, and confirm panes reach their transcript without a manual reload. Watch the console: you'll see the existing [xcript-diag] RESOLVE-DROPPED … followed by [xcript-heal #283] re-drove N stuck pane(s) … and then ready-set — that sequence is the heal working.

The #284 [xcript-diag] logs are intentionally left in for this validation; remove them in a follow-up cleanup once confirmed.

🤖 Generated with Claude Code

…esume

The committed-transcript channel can fail to attach on resume/rehydrate: the
load's terminal 'ready'/'error' write is discarded when its runtime key is
dropped or re-keyed mid-flight (the RESOLVE-DROPPED / ERROR-DROPPED paths from
the #284 instrumentation), OR the pane is marked 'loading' by rehydrate but no
loader is ever kicked. Either way the pane spins forever — or paints an empty
"waiting for…" feed with the user's prompts missing — until a manual reload
re-runs the loader under a now-stable id.

This automates that manual reload:

- Track in-flight initial-history loads in a module-level Set (added before the
  'loading' write, cleared in a finally on every exit incl. dropped-write).
- reconcileStuckTranscriptLoads(): scan current runtimes for panes that are
  (a) stuck at 'loading', (b) not currently loading, (c) backed by a durable
  provider session, and re-drive the load for each. Conservative — only touches
  already-broken panes, no-op otherwise.
- useBootstrap schedules three detached sweeps (1.5s/4s/8s after rehydrate) so
  a slow first load settles before we treat a pane as stuck, and panes that
  only become stuck after their dropped load resolves still get caught.

Covers both failure modes (dropped-write race AND marked-loading-never-loaded).
Renderer-only; typechecks clean. The #284 [xcript-diag] logs are left in place
so the heal can be verified against them, then removed in a cleanup once
confirmed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Juliusolsson05

Copy link
Copy Markdown
Owner Author

Superseded — applying the auto-heal directly to the main working tree for live testing instead of via PR, per maintainer request. Same change (broadened to also re-drive empty-feed panes, not just the spinner).

@Juliusolsson05
Juliusolsson05 deleted the fix/283-autoheal-stuck-transcripts branch June 18, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant