Skip to content

win: handle short path mismatch with a fallback in fs events - #5152

Merged
santigimeno merged 1 commit into
libuv:v1.xfrom
joyeecheung:fix-win-short
Jun 10, 2026
Merged

santigimeno merged 1 commit into
libuv:v1.xfrom
joyeecheung:fix-win-short

Conversation

@joyeecheung

@joyeecheung joyeecheung commented May 29, 2026 •

Copy link
Copy Markdown
Contributor

uv_fs_event_start() stores the watched directory path verbatim in handle->dirw. When an event arrives, the child path is resolved to its long form with GetLongPathNameW() and uv__relative_path() strips the handle->dirw prefix off the result. Previously if the directory was supplied as an 8.3 short path, the long form no longer shares that prefix, so the prefix check in uv__relative_path() fails, which either fires an assertion in builds without NDEBUG or produces a wrong(potentially out-of-bounds) result otherwise.

This patch falls back to the name reported by ReadDirectoryChangesW in this case, since that is already relative to the watched directory, similar to how other branches handle it since this is the least race-prone option.

Also update the test to try testing under %TEMP% if accessible to increase the chance of it reproducing in the CI.

Fixes: #5010

uv_fs_event_start() stores the watched directory path verbatim in
handle->dirw. When an event arrives, the child path is resolved to its
long form with GetLongPathNameW() and uv__relative_path() strips the
handle->dirw prefix off the result.

Previously if the directory was supplied as an 8.3 short path, the
long form no longer shares that prefix, so the prefix check in
uv__relative_path() fails, which either fires an assertion in
builds without NDEBUG or produces a wrong(potentially
out-of-bounds) result otherwise.

This patch falls back to the name reported by ReadDirectoryChangesW
in this case, since that is already relative to the watched directory,
similar to how other branches handle it.

Also update the test to try testing under %TEMP% if accessible to
increase the chance of it reproducing in the CI.
@joyeecheung

Copy link
Copy Markdown
Contributor Author

Locally the test reproduces without my fix if I run it on a system volume (where 8.3 short name is enabled). I also confirmed with a test in my fork that the updated test can reproduce the failure in github actions (where the %TEMP% is on a volume that enables short path, from what I can tell). https://github.com/joyeecheung/libuv/actions/runs/26667915142/job/78605141207

@joyeecheung

Copy link
Copy Markdown
Contributor Author

The Android failure looks unrelated, not sure if it's a flake?

@joyeecheung

joyeecheung commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor Author

@vtjnash Thanks for the review! The failure has been affecting the github actions in many downstream projects so it would be nice if a fix can be merged and rolled into Node.js. Anything else needed before it can be merged?

@santigimeno
santigimeno merged commit e640dc9 into libuv:v1.x Jun 10, 2026
43 of 44 checks passed
nodejs-github-bot pushed a commit to nodejs/node that referenced this pull request Aug 14, 2026
Signed-off-by: ulofiai <monsterking@tutamail.com>
PR-URL: #65118
Fixes: #63638
Refs: libuv/libuv#5152
Refs: libuv/libuv@e640dc9
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
aduh95 pushed a commit to nodejs/node that referenced this pull request Aug 25, 2026
Signed-off-by: ulofiai <monsterking@tutamail.com>
PR-URL: #65118
Fixes: #63638
Refs: libuv/libuv#5152
Refs: libuv/libuv@e640dc9
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
aduh95 pushed a commit to nodejs/node that referenced this pull request Aug 25, 2026
Signed-off-by: ulofiai <monsterking@tutamail.com>
PR-URL: #65118
Fixes: #63638
Refs: libuv/libuv#5152
Refs: libuv/libuv@e640dc9
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
aduh95 pushed a commit to nodejs/node that referenced this pull request Aug 27, 2026
Signed-off-by: ulofiai <monsterking@tutamail.com>
PR-URL: #65118
Fixes: #63638
Refs: libuv/libuv#5152
Refs: libuv/libuv@e640dc9
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
stefanhoelzl added a commit to stefanhoelzl/codehydra that referenced this pull request Sep 28, 2026
VSCodium stays at 1.126.04524: 1.135.06055 bundles Node 24.18.1, whose
libuv aborts on Windows when a watched directory has an 8.3 short name
(fs-event.c `_wcsnicmp` assertion; libuv/libuv#5152, fixed in Node 24.21.0).
In the Windows e2e it took down the extension host and the agent terminals.
The note at VSCODIUM_VERSION says what to wait for.

Every npm dependency is on its latest release except:
- typescript ~6.0: typescript-eslint and svelte-check do not support 7 yet
- vite 7 / vite-plugin-svelte 6: electron-vite 5 caps vite at 7 (the
  markdown editor, which has no electron-vite, is on vite 8)
- happy-dom ~20.11: 20.12's Animation rejects `finished` on cancel without
  marking it handled, so every cancelled Svelte transition is an unhandled
  rejection in tests
- @vscode/codicons 0.0.45: npm's latest tag is a prerelease
- @types/vscode ~1.134: must not outrun the VSCodium we ship

Migrations the majors required:
- simple-git 4: named `simpleGit` export, and its environment guard. The
  user's environment is passed through as before: every key present is
  allowed and exactly the unsafe categories simple-git's own checker reports
  for it are enabled (argument checks stay on for the rest). Clone now runs
  with that environment too. Boundary tests cover git running with EDITOR/
  GIT_ASKPASS/GIT_SSH_COMMAND set and GIT_CONFIG_* reaching git.
- TypeScript 6: drop the deprecated baseUrl (paths are tsconfig-relative)
  and node10 resolution; vite/client types for the editor's CSS import
- vitest 5: augment Matchers<R, T> instead of Assertion<T>, whose own
  declarations no longer agree; the state-mock lint exemption covers R
- vite-plugin-static-copy 4: preserves directory structure, so every
  target strips its base (asset layout verified identical)
- zod 4.6 ships a misplaced @__PURE__ comment; allow INVALID_ANNOTATION
  from node_modules like the other dependency warnings
- Prettier 3.9 reformat; fix the API.md conventions table whose unescaped
  pipes split a cell

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stefanhoelzl added a commit to stefanhoelzl/codehydra that referenced this pull request Sep 29, 2026
VSCodium stays at 1.126.04524: 1.135.06055 bundles Node 24.18.1, whose
libuv aborts on Windows when a watched directory has an 8.3 short name
(fs-event.c `_wcsnicmp` assertion; libuv/libuv#5152, fixed in Node 24.21.0).
In the Windows e2e it took down the extension host and the agent terminals.
The note at VSCODIUM_VERSION says what to wait for.

Every npm dependency is on its latest release except:
- typescript ~6.0: typescript-eslint and svelte-check do not support 7 yet
- vite 7 / vite-plugin-svelte 6: electron-vite 5 caps vite at 7 (the
  markdown editor, which has no electron-vite, is on vite 8)
- happy-dom ~20.11: 20.12's Animation rejects `finished` on cancel without
  marking it handled, so every cancelled Svelte transition is an unhandled
  rejection in tests
- @vscode/codicons 0.0.45: npm's latest tag is a prerelease
- @types/vscode ~1.134: must not outrun the VSCodium we ship

Migrations the majors required:
- simple-git 4: named `simpleGit` export, and its environment guard. The
  user's environment is passed through as before: every key present is
  allowed and exactly the unsafe categories simple-git's own checker reports
  for it are enabled (argument checks stay on for the rest). Clone now runs
  with that environment too. Boundary tests cover git running with EDITOR/
  GIT_ASKPASS/GIT_SSH_COMMAND set and GIT_CONFIG_* reaching git.
- TypeScript 6: drop the deprecated baseUrl (paths are tsconfig-relative)
  and node10 resolution; vite/client types for the editor's CSS import
- vitest 5: augment Matchers<R, T> instead of Assertion<T>, whose own
  declarations no longer agree; the state-mock lint exemption covers R
- vite-plugin-static-copy 4: preserves directory structure, so every
  target strips its base (asset layout verified identical)
- zod 4.6 ships a misplaced @__PURE__ comment; allow INVALID_ANNOTATION
  from node_modules like the other dependency warnings
- Prettier 3.9 reformat; fix the API.md conventions table whose unescaped
  pipes split a cell

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
openwong2kim added a commit to openwong2kim/wmux that referenced this pull request Sep 29, 2026
libuv 1.52.x on Windows (Node 24.16-24.20, and the Node 24.18.0 inside
Electron 41) stores a watched directory's path verbatim, expands each
event's path to its long form, and asserts the watched directory is its
prefix (src/win/fs-event.c:72). A directory spelled with an 8.3 short
component - the windows-latest runner's %TEMP% is C:\Users\RUNNER~1\... -
fails that check:

- official Node builds (asserts on) abort the process. That is the
  vitest fork death in #984: TranscriptProjector.test.ts and
  codexCapture.test.ts watch directories under os.tmpdir().
- Electron (asserts off) reports a garbled filename (the tail of the
  long path, e.g. "rt-a1B2c3\.git\HEAD"), so GitContextWatcher's HEAD
  filter drops the event and the sidebar branch stops updating for a
  cwd spelled that way.

Regressed in libuv/libuv#4948 (1.52.0), fixed in libuv/libuv#5152
(1.53.0; cherry-picked into Node 24.21.0). Node 22 ships libuv 1.51,
which still expanded the watched directory up front.

watchTarget() hands fs.watch the realpathSync.native spelling on
Windows (falling back to the input, so a missing directory still throws
and the poll fallbacks still fire). Applied to the three directory
watchers: GitContextWatcher, TranscriptProjector, TranscriptDiscovery.
fs.handler already watches an fs.promises.realpath result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQRsu2jy3jc1LT1HQRzoka
openwong2kim pushed a commit to openwong2kim/wmux that referenced this pull request Oct 10, 2026
"24.21.0 or later" also admitted 26.0-26.7, which ship the same libuv
1.52.1 without libuv/libuv#5152. Name the affected ranges and the fixed
releases on each line instead (CodeRabbit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
openwong2kim added a commit to openwong2kim/wmux that referenced this pull request Oct 11, 2026
…cher fix (#2059)

* ci: run the test jobs on Node >= 24.21.0, which carries the libuv watcher fix (#984)

The vitest fork death on windows-latest was libuv 1.52.1's assert in
src\win\fs-event.c (libuv/libuv#4948) on directory watches under the
runner's 8.3 %TEMP%. Official Node 24.16.0-24.20.0 ship it; 24.21.0
cherry-picked libuv/libuv#5152.

validate, validate-runtime and computer-use-windows move to a
'>=24.21.0 <25' floor (a bare 24 resolved from the tool cache to
24.19.0); the cross-platform baseline takes the floor on its Windows
leg and plain 24 elsewhere. The npm 11 install step stays so the
lockfile lineage guard runs the same npm as release.yml, perf.yml and
CONTRIBUTING. perf.yml and release.yml stay on Node 22 for now.
CONTRIBUTING notes the 24.21.0 floor for Windows contributors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: keep the non-Windows baseline legs on Node 22 (#984)

On Node 24 the macOS leg failed 6 files (DaemonPipeServer, SessionPipe.*,
DaemonClient): their unix socket paths under macOS's long $TMPDIR are
110 bytes, past the 104-byte sun_path limit. Node 22 truncated them
silently; Node 24 rejects them with EINVAL. The libuv watcher bug is
Windows-only, so only the Windows leg needs the new runtime; the socket
path length is a separate follow-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(contributing): name both affected Node lines for Windows (#984)

"24.21.0 or later" also admitted 26.0-26.7, which ship the same libuv
1.52.1 without libuv/libuv#5152. Name the affected ranges and the fixed
releases on each line instead (CodeRabbit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: woyoungkim <wykim777@naver.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

win: Assertion failure in fs_event_watch_dir_short_path

3 participants