Repository navigation
fix(history): tell the user when an older-history page fails to load (#1250 row 12) - #1413
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1250 row 12) loadOlderHistory now answers loaded/skipped/failed; TileLeaf shows a fixed, coalesced pane toast on failed. hasOlderHistory stays set so the next scroll to the top retries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Steering q106 fixed ( 🤖 Generated with Claude Code |
…view a, b) Also records in the plan that e905104 carried the loader fix (an unreadable transcript now rejects an older page instead of paging it as empty). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review disposition, round 1 (head
|
| Finding | Disposition |
|---|---|
a1: an unreadable transcript was paged as an empty page with hasMore: false, so the feed silently lost "older exists" |
Fixed (e905104e). The older-page reader (used only for paging) now rejects on a stat, open or read failure, so the page is failed and retryable. An empty file is still an empty page, and the initial-chunk reader is unchanged. The test (the first page loads, the file is removed, the older page rejects with ENOENT) fails on the old loader. |
| a2 / b1: "Scroll up again to retry" was impossible at scrollTop 0 (no scroll event) | Fixed (f72f8670). An upward wheel at the top makes the same request. The real-Feed test (two upward wheels at 0 make two requests; a downward wheel makes none) fails on the old Feed and kills a's loadingOlderRef survivor. |
| b2: the cooldown was shared across agents in one lane | Fixed (q106, e905104e). |
b3 (minor): the raw error reaches console.warn and the perf span |
Declined. These are developer diagnostics, not user-visible text, and q22 governs what the user sees. The perf journal records the file path on this path by design (finishOlderChunk). |
Verification:
npx tsc -b: clean.src/main/sessions,src/main/remote,features/feed/ui,workspace/hook/actionsand the TileLeaf older-history test: 494/494.
🤖 Generated with Claude Code
… target pane (#1413 review c) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Reviewer c: MERGE-READY, four minor test gaps, all pinned in 🤖 Generated with Claude Code |
#1413 verification b) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Verification b: FIX-BEFORE-MERGE, fixed in 🤖 Generated with Claude Code |
…1413 verification a) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Verification a: FIX-BEFORE-MERGE, fixed in Verification: Round count: round 1 and verification are done, so the review is capped. The PR waits for CI and the manager gate. 🤖 Generated with Claude Code |
Refs #1250 (row 12). #1250 is a batch issue, so the other rows stay open.
Problem
Scrolling to the top of an agent feed pages in older history. When that page failed (the IPC rejected, or the transcript could not be read),
useHistoryActions.loadOlderHistoryonly warned to the console and clearedloadingOlderHistory. It returned nothing, so no caller could tell a failure from a load, and the feed simply looked as if it had nothing older.Change
loadOlderHistoryanswers'loaded' | 'skipped' | 'failed'(OlderHistoryLoadResult).failedcomes only from the catch, which leaveshasOlderHistoryset so the next scroll to the top retries.skippedis every early return.TileLeafshows a pane toast onfailed: "Couldn't load older messages. Scroll up again to retry."readOlderTranscriptWindow) or one the resolver can no longer find (loadOlderHistoryChunk, e.g. a Codex rollout) now rejects instead of paging an emptyhasMore: false. So it is a failed, retryable page. An empty file is still an empty page, and the initial-chunk reader is unchanged.Feed: an upward wheel or a downward touch drag atscrollTop0 also requests the older page, so "scroll up again" works at the top, where no scroll event fires.AgentFeed/FeedkeeponLoadOlderHistory: () => Promise<void>. The phone is untouched.Plan:
docs/plans/2026-09-27-load-older-history-failure.md.Tests (red on main)
history.renderer.test.tsx: a rejecting page read givesfailedand keepshasOlderHistory; a page givesloaded; a missing marker givesskipped.New
TileLeaf.olderHistory.renderer.test.tsx: Feed is probed for the REALonLoadOlderHistoryprop TileLeaf passes through AgentFeed. A failure toasts the fixed text once per burst and again after the window;loadedandskippedtoast nothing. A lane switch to another agent within the window still toasts that agent's failure.historyLoader.test.ts: an older page of a transcript removed after its first page rejects with ENOENT; an empty file stays empty.New
Feed.olderHistory.renderer.test.tsx: the real Feed. Two upward wheels at the top make two requests; a downward wheel makes none. A downward finger drag makes one; an upward drag makes none.historyLoader.providerOwned.test.ts: an older Codex page whose rollout can no longer be resolved rejects.Verification
rm -rf .tsc-out; npx tsc -b: clean.NODE_ENV=test npx vitest run src/main/sessions src/main/remote src/renderer/src/features/feed/ui src/renderer/src/workspace/hook/actionsplus the TileLeaf older-history test: 499/499.🤖 Generated with Claude Code