Skip to content

File preview can keep serving cached content after an agent modifies the file #5866

Description

@isaachorowitz

What happened

I opened a Markdown file in the file preview panel and switched it to the readable/formatted view. An agent then modified that same file. From that point on the panel kept showing the old content — the agent's changes never appeared, and the diff showed nothing either. Reopening the file showed the pre-edit content.

The project was a local folder with no remote at the time. I pushed it to GitHub thinking that might matter, and the behaviour was unchanged — which in hindsight fits, since nothing about this looks git-related.

What I found in the code

Reading at 02f4ce56, there's a path where a file's cached content can outlive the file itself.

useProjectFileQuery returns the optimistic entry in preference to the query result:

  • apps/web/src/components/files/projectFilesQueryState.ts:194data: optimisticFile?.data ?? data
  • same again in resolveProjectFileQueryData, projectFilesQueryState.ts:107

So while an optimistic entry exists for (environmentId, cwd, relativePath), it masks whatever is actually on disk.

That entry is cleared in exactly one place — the success branch after a save is confirmed:

  • projectFilesQueryState.ts:93-94if (result._tag === "Success" && appAtomRegistry.get(atom) === confirmed) { appAtomRegistry.set(atom, null) }

If that re-read doesn't succeed, or the atom moved on in between, the entry stays. I couldn't find anything that drops it afterwards, and in particular I couldn't find any invalidation of a file's query when something outside the editor — an agent tool call — writes that file.

Two things that look related:

  • clearProjectFileQueryData (projectFilesQueryState.ts:110) does exactly this job, and has no callers outside its own definition and projectFilesQueryState.test.ts.
  • confirmedAgainst is written at :54 and :85 but never read anywhere. It reads like a staleness check that wasn't finished.

What I have not verified

I traced this from the source; I have not reproduced it from a clean checkout with a deterministic trigger, and I don't know what made the confirm step fail in my case. So treat the mechanism as a strong hypothesis rather than a diagnosis. It does explain every part of what I saw, including it persisting across reopening the file.

Happy to send a PR

I didn't open one because the fix is a decision rather than a line: the right place to drop optimistic state could be on agent tool completion, on a file-watcher event, or on any external write, and that's your call rather than mine. If you tell me which invalidation point you want, I'll keep it small and focused.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions