fix(sessions): keep tail follow cursor aligned with bytes actually read#108127
Merged
steipete merged 3 commits intoJul 15, 2026
Merged
Conversation
sunlit-deng
force-pushed
the
sunlit/fix/sessions-tail-short-read
branch
2 times, most recently
from
July 15, 2026 10:59
4e51281 to
a3e5107
Compare
sunlit-deng
force-pushed
the
sunlit/fix/sessions-tail-short-read
branch
from
July 15, 2026 15:13
a3e5107 to
108f07b
Compare
Contributor
|
Merged via squash.
|
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Jul 16, 2026
…ad (openclaw#108127) * fix(sessions): keep tail follow cursor aligned with bytes actually read * refactor(infra): share synchronous file window reads Co-authored-by: sunlit-deng <[email protected]> --------- Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
steipete
pushed a commit
to Monkey-wusky/openclaw
that referenced
this pull request
Jul 16, 2026
Replace single-shot handle.read() calls in two session tail-read paths with readFileWindowFully so multibyte-range positional reads do not silently return incomplete tail data on network filesystems. - readRecentTranscriptTailLinesAsync: tail-window read for recent session messages now loops until the requested window fills - readLastMessagePreviewFromOpenTranscriptAsync: last-message preview tail read now loops until the requested window fills The same readFileWindowFully helper was introduced in openclaw#108253 and expanded with a sync variant in openclaw#108127 (both by sunlit-deng).
steipete
pushed a commit
to Monkey-wusky/openclaw
that referenced
this pull request
Jul 16, 2026
Replace single-shot handle.read() calls in two session tail-read paths with readFileWindowFully so multibyte-range positional reads do not silently return incomplete tail data on network filesystems. - readRecentTranscriptTailLinesAsync: tail-window read for recent session messages now loops until the requested window fills - readLastMessagePreviewFromOpenTranscriptAsync: last-message preview tail read now loops until the requested window fills The same readFileWindowFully helper was introduced in openclaw#108253 and expanded with a sync variant in openclaw#108127 (both by sunlit-deng).
steipete
pushed a commit
to Monkey-wusky/openclaw
that referenced
this pull request
Jul 16, 2026
Replace single-shot handle.read() calls in two session tail-read paths with readFileWindowFully so multibyte-range positional reads do not silently return incomplete tail data on network filesystems. - readRecentTranscriptTailLinesAsync: tail-window read for recent session messages now loops until the requested window fills - readLastMessagePreviewFromOpenTranscriptAsync: last-message preview tail read now loops until the requested window fills The same readFileWindowFully helper was introduced in openclaw#108253 and expanded with a sync variant in openclaw#108127 (both by sunlit-deng).
steipete
added a commit
that referenced
this pull request
Jul 16, 2026
…ads (#108655) * fix(sessions): complete tail-read windows despite short positional reads Replace single-shot handle.read() calls in two session tail-read paths with readFileWindowFully so multibyte-range positional reads do not silently return incomplete tail data on network filesystems. - readRecentTranscriptTailLinesAsync: tail-window read for recent session messages now loops until the requested window fills - readLastMessagePreviewFromOpenTranscriptAsync: last-message preview tail read now loops until the requested window fills The same readFileWindowFully helper was introduced in #108253 and expanded with a sync variant in #108127 (both by sunlit-deng). * fix(sessions): complete sync title preview reads --------- Co-authored-by: Peter Steinberger <[email protected]>
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Jul 17, 2026
…ads (openclaw#108655) * fix(sessions): complete tail-read windows despite short positional reads Replace single-shot handle.read() calls in two session tail-read paths with readFileWindowFully so multibyte-range positional reads do not silently return incomplete tail data on network filesystems. - readRecentTranscriptTailLinesAsync: tail-window read for recent session messages now loops until the requested window fills - readLastMessagePreviewFromOpenTranscriptAsync: last-message preview tail read now loops until the requested window fills The same readFileWindowFully helper was introduced in openclaw#108253 and expanded with a sync variant in openclaw#108127 (both by sunlit-deng). * fix(sessions): complete sync title preview reads --------- Co-authored-by: Peter Steinberger <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
Fixes an issue where
openclaw sessions tail --followsilently loses trajectory events. The file-follow poller (readNewFileFollowEventsinsrc/commands/sessions-tail.ts) reads the appended delta with onefs.readSync, ignores the returned byte count, and unconditionally jumps the cursor tostat.size. When the positional read returns short — a documented POSIX behavior, common on network filesystems — the unread bytes are skipped forever and the undecoded remainder of the buffer becomes NUL garbage in the JSONL line parser, so the affected events never render and never get retried.Why This Change Was Made
The follow cursor now advances only past the bytes actually read (
state.offset += bytesRead) and only those bytes are decoded (buffer.subarray(0, bytesRead)), so the next poll picks up the remainder instead of skipping it. This follows the short-read-safe direction of #105066 (readLogWindowFullyfor log tails); the existing rotation/truncation rescan checks above this read are unchanged.User Impact
sessions tail --followdelivers every appended trajectory event even when reads return short, instead of silently dropping events for the rest of the follow session.Evidence
node scripts/run-vitest.mjs run src/commands/sessions-tail.test.ts— main:Timed out waiting for output containing python ok(the appended event is never delivered); this branch: 13 passed.sessionsTailCommandfollow path against a real trajectory JSONL file. The documented POSIX short-read contract is applied at thefs.readSyncboundary (each capped call still performs a real kernel read of the real file); an event is appended mid-follow and we observe whether it ever renders.Baseline (main @ 5afb1fb):
After (this branch, same script and input):
live-proof.mjs (save in repo root, run with `node --import tsx live-proof.mjs`)
AI-assisted: built with Codex