Skip to content

[Tracking] Edit tool reliability: "modified since last read" errors (Undo/Redo & Persistence) #5840

@AdiY00

Description

@AdiY00

Note: This is a tracking issue to make the Edit tool more reliable. It covers the immediate fixes we're working on and a plan for the long-term solution.

Related PRs & Issues

The Problem

The Edit tool frequently rejects valid operations with the error File [...] has been modified since it was last read in two common scenarios:

  1. Undo/Redo: When reverting a chat to a previous state using /undo or the UI.
  2. Session Persistence: When reopening a session after a restart or reloading the window.

In both cases, the model often has the correct context (either restored from history or "remembered" from the session), but the internal safety check fails, forcing redundant Read calls and wasting valid Edit calls (which can be expansive and take a long time for big edits).

Root Cause

The current FileTime implementation relies on in-memory timestamps (Date) compared against the filesystem's mtime.

  • Undo/Redo: Reverting files via git snapshots updates their mtime on disk, making them appear "newer" than the last time the model read them, even if the content is exactly what the model expects.
  • Persistence: The FileTime state is stored in memory (Instance.state). When the server restarts, this state is lost, so any subsequent edit attempts fail until the file is read again.

Proposed Solutions

1. Immediate Fixes

Two separate PRs address the immediate pain points:

A. Fix for Undo/Redo (PR #4923)

This PR manually updates the FileTime entry for affected files whenever a revert or unrevert operation occurs.

  • Pros: Solves the immediate friction for undo/redo.
  • Cons: It blindly trusts that the model has read the file in the context we are reverting to. If we revert to a point before the file was read, this allows an edit without a read. However, this is a much rarer scenario (since most models reliably use the read tool if they haven't seen the file before). Even though it IS a risk, it's still way better than the current state.

B. Fix for Session Persistence (PR #5045)

This PR persists the FileTime state to disk using the Storage module.

  • Mechanism: Writes timestamps to ["filetime", sessionID, encodedPath] so the "last read" time survives server restarts.
  • Pros: Prevents unnecessary re-reads after reloading the window or restarting the server.

2. Long-term Solution (Persisted Content Hashing)

A more robust architecture would replace or augment the timestamp check with context-aware content hashing.

  • Mechanism: Maintain a map of filePath -> contentHash linked to the session history.
  • Persistence: Store this map using the Storage module (similar to PR feat: writing filetime reads to disk to persist across process being killed #5045) so it survives restarts.
  • Context Awareness: When performing an undo, the system would restore the hash map to its state at that point in history.
  • Verification: The Edit tool would check if the current on-disk hash matches the "expected" hash from the session state. If they match, the edit proceeds regardless of the timestamp.

Discussion

I'm down to implement the hashing solution, but I wanted to sanity check the direction first.

OpenCode version

No response

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions