Skip to content

fix(web): roll back file editor when save fails - #8424

Open
Adolanium wants to merge 5 commits into
pingdotgg:mainfrom
Adolanium:fix/file-save-overlay-rollback
Open

fix(web): roll back file editor when save fails#8424
Adolanium wants to merge 5 commits into
pingdotgg:mainfrom
Adolanium:fix/file-save-overlay-rollback

Conversation

@Adolanium

@Adolanium Adolanium commented Aug 27, 2026

Copy link
Copy Markdown

What Changed

The file editor now restores the last confirmed text when a save fails.

Edits still apply to the overlay first. If the latest write fails, the overlay goes back, the unsaved mark clears, and a toast says the save failed. A newer edit that landed during that write is not rolled back. The coordinator retries it.

Why

A failed write left the new text on screen. Reload then showed the old disk contents. Easy to think the file was saved.

UI Changes

Failed saves now toast and restore the last confirmed file text. No other visual change.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (N/A. toast plus restored text is the change)
  • I included a video for animation/interaction changes (N/A)

Note

Medium Risk
Changes autosave and optimistic file cache behavior on write failure; incorrect rollback could drop user edits or show stale disk content, though guards exist for newer overlay edits and interrupted commands.

Overview
Failed file writes no longer leave optimistic editor text on screen. FileSaveCoordinator now tracks lastConfirmedContents (from initialContents and successful saves), exposes syncConfirmed so idle server refreshes update the rollback baseline, and on a non-interrupted persist failure resets internal state and invokes onRollback instead of leaving the file “saved.” Interrupted writes and in-flight newer edits are unchanged: stale failures do not roll back newer typing, and overlapping saves still debounce to the latest revision.

FilePreviewPanel wires this up by passing loaded contents, syncing confirmed text when contents changes without rebuilding the coordinator on every keystroke, and implementing onRollback to restore project file query data, clear pending when appropriate, skip rollback if the overlay already diverged, and show a “Could not save file” error toast.

Tests cover rollback, baseline refresh, interrupted/dispose edge cases, and concurrent edit behavior.

Reviewed by Cursor Bugbot for commit de49ca5. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Roll back file editor to last confirmed contents on save failure

  • FileSaveCoordinator now tracks a lastConfirmedContents baseline, seeded from a new initialContents option and updated on successful saves and idle external refreshes via syncConfirmed.
  • On save failure, the coordinator restores latestContents to the baseline, resets latestRevision to 0, and invokes a new onRollback callback with failedContents, confirmedContents, and the persist result; pending state is intentionally left uncleared so the UI can mark the file as pending.
  • Write interruptions detected by isAtomCommandInterrupted are treated as a distinct case — no rollback, no pending change.
  • useFileSaveCoordinator wires initialContents and a new useEffect that calls coordinator.syncConfirmed(contents) on external content changes, and implements onRollback to reset query data and show an error toast.
  • Behavioral Change: pending state is no longer cleared on save failure or interruption; callers that relied on pending being cleared after a failed save will need updating.

Macroscope summarized de49ca5.

The editor showed new text before the disk write finished. A failed write left that text on screen and kept the file marked unsaved. Reload then showed the old file.

On a failed save of the latest edit, restore the last confirmed text, clear the unsaved mark, and toast.
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 67ea28a0-c91d-4bad-80c9-82de018b4366

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 27, 2026
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
Comment thread apps/web/src/components/files/fileSaveCoordinator.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI consistency review found three issues in the new file-save rollback path. The main one is that an interrupted write is now treated as a failed write, which makes the editor discard the user's text and surface a save error — every other command result handler in apps/web filters interrupted results out first.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/files/fileSaveCoordinator.ts Outdated
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
Comment thread apps/web/src/components/files/fileSaveCoordinator.ts Outdated
Comment thread apps/web/src/components/files/fileSaveCoordinator.ts Outdated
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at de49ca5

Macroscope's review found this PR approvable — This is a focused fix to restore the last confirmed file contents after autosave failures, with guarded handling for concurrent edits and interrupted writes. Production changes are confined to the file editor flow and are accompanied by targeted coordinator tests.

You can add or adjust custom eligibility rules. Learn more.

A failed save rolled the overlay back even when the write was interrupted, the coordinator was unmounted, or a newer edit already sat in the shared cache. Dispose could then write the discarded text.

Skip interrupt and unmount. Clear the overlay only if it still matches the failed write. Use a later idle refresh as the confirmed baseline. Toast the write error.
Comment thread apps/web/src/components/files/fileSaveCoordinator.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the rollback toast calls squashAtomCommandFailure on an un-narrowed AtomCommandResult, which does not typecheck. Details inline.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/files/FilePreviewPanel.tsx Outdated
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx Outdated
A write that failed after dispose left the next surface showing the optimistic text and still marked unsaved. Rollback now still runs. If a newer overlay is already there, keep that text and mark the file pending again.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new after-dispose rollback path: the coordinator's unconditional onPendingChange(false) cancels the "mark pending again" branch that onRollback uses when a newer overlay is present, so the file tab loses its unsaved indicator while unsaved text is still on screen.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/files/fileSaveCoordinator.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit dc19c82. Configure here.

Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
The coordinator was clearing pending right after onRollback, which wiped the unsaved mark when a newer overlay was kept. Rollback now sets pending itself.

Failed saves restore the last confirmed text in the overlay, then confirm it, so a stale readFile does not flash the pre-save file. The toast only squashes Failure results.
Comment thread apps/web/src/components/files/fileSaveCoordinator.ts
A successful save left latestRevision set, so idle query refreshes never updated lastConfirmedContents. A later failed edit then rolled back to the old local save instead of the file now on disk.

Reset latestRevision after a successful latest write.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant