fix(documents): read through the checked command everywhere, and stop the auto-save toast repeating - #406
Merged
PathGao merged 1 commit intoAug 3, 2026
Conversation
… the auto-save toast from repeating #379 added `read_file_content_checked` so a lossily decoded buffer can refuse to overwrite its source. Three call sites kept the bare command - `toggleEdit`, `toggleSplitView`, `ensureFullContent`. They were safe, but by an argument rather than by construction: each re-reads a file whose tab is already flagged. That is two call sites agreeing with each other, and it holds only until someone adds a fourth reader. All three now read through `_checked` and set the flag from what they read, which also clears a stale flag on a file since converted to UTF-8. `ensureFullContent` is the one with a live hazard: it replaces a >50KB preview with the whole file, and a file can be valid UTF-8 for its first 50KB and not after. Separately, a refused save returns false, and the auto-save timer treated that like any other failure - so the generic "Auto-save failed" toast fired on every re-arm while the user typed, even though the specific explanation appears once per tab. The generic toast is now suppressed when the refusal has explained itself, and a refused tab stops re-arming. The first attempt still runs, since that is what produces the explanation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PathGao
force-pushed
the
fix/checked-reads-and-autosave-toast
branch
from
August 2, 2026 23:11
53bbe04 to
971dc2d
Compare
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.
1. Three call sites still used the unchecked read
#379 added
read_file_content_checked, returning(content, lossy)so a buffer decoded with U+FFFD substitutions can refuse to overwrite its source. Three places kept the bare command:toggleEdit,toggleSplitView,ensureFullContent.They were safe — but by an argument, not by construction: each re-reads a file whose tab
loadMarkdownhas already flagged, andsetTabRawContentdoes not clear the flag. That is two call sites agreeing with each other, and it holds only until someone adds a fourth reader.All three now read through
_checkedand set the flag from what they read. That also clears a stale flag on a file converted to UTF-8 since it was opened — the old arrangement could carry a flag forward but never retire it.ensureFullContentis the one with a live hazard rather than a hypothetical: it replaces a >50KB preview buffer with the whole file, and a file can be valid UTF-8 for its first 50KB and not after. Its tail now brings its own verdict.2. The auto-save toast repeated every 1.5s
When #379's guard refuses a save,
saveContentreturnsfalse, and the auto-save timer treated that like any other failure — so the generic "Auto-save failed" fired on every re-arm while the user typed, even though the specific explanation appears once per tab.Two layers: the generic toast is suppressed once the refusal has explained itself, and a refused tab stops re-arming the timer. The first attempt still runs — that is what produces the explanation. "Save As" to a different file clears
hasReplacementChars, restoring eligibility with nothing to remember.Tests
scripts/checkedReadMigration.test.ts— theensureFullContenttests run the real session and prove the tail's own verdict reaches the tab.checkedReadMigration.test.tslossyDecodeSaveGuard.test.ts's bare-command count tightens 1 → 0.🤖 Generated with Claude Code