Skip to content

Bug: file watcher paths stop matching open files on Windows #17780

@jb-sk

Description

@jb-sk

What happened?

On Windows, file watcher updates can fail to refresh both:

  • files shown in the file tree
  • files already open in tabs

This happens when watcher events use backslash-separated paths while the app store / tab state uses slash-separated paths.

As a result, external file changes or tool-driven edits can be missed even though the watcher event itself arrives.

In my testing, this is not limited to unloaded descendants. Directory contents can also fail to refresh even when the relevant directory is already visible.

Steps to reproduce

  1. Run OpenCode on Windows.
  2. Open a file in a tab.
  3. Modify that file through a tool action or an external process.
  4. Observe that the open tab content does not always refresh.
  5. Create, remove, or change files in a directory shown in the file tree.
  6. Observe that directory contents may fail to refresh in the file tree, including cases where the directory is already visible.

Expected behavior

  • Watcher paths should match store/tab paths consistently on Windows.
  • Open files should refresh when watcher updates arrive.
  • File tree refresh should work reliably when directory contents change.

Actual behavior

  • Watcher updates can be ignored because normalized paths do not match.
  • Open tabs stay stale.
  • File tree refresh can be skipped or missed when directory contents change.

Suspected cause

normalize() can preserve Windows \ separators for watcher-originated paths, while other app paths are compared in / form.

There also appears to be a watcher refresh gap in directory invalidation / refresh behavior, not just a path-key mismatch.

Proposed fix

  • Normalize watcher path comparisons consistently so Windows paths match the existing store/tab keys.
  • Make watcher-driven directory refresh behavior reliable when file system changes occur, including directories that are already visible.

Additional context

This may be related to the separator-preserving behavior introduced for Windows / Cygwin compatibility in PR #14912:
#14912

However, the current behavior appears to break watcher-to-store comparisons in the app UI and also misses some file tree refresh cases.

Metadata

Metadata

Assignees

Labels

No labels
No labels

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