[BUG] Windows: claude plugin eval fails with ENAMETOOLONG uv_spawn when the plugin dir holds ~3.5K chars of summed junction paths
What happens
On Windows, claude plugin eval <plugin-dir> fails every case with
ENAMETOOLONG: name too long, uv_spawn
before any child process starts, once the plugin directory contains enough NTFS junctions. With pnpm's default (isolated) layout, node_modules/ inside the plugin root holds hundreds of junctions into .pnpm, which is enough to trigger it. Every case then scores 0.
Environment
- Claude Code 2.1.278 (also seen on 2.1.280), Windows 11 Pro 22631, Git Bash
- Plugin root at a ~60-character path under
C:\Users\<user>\...
What was measured
Three arms, same machine, same Claude Code version:
| arm | reparse points in plugin dir | result |
|---|---|---|
| the repository as it was (pnpm isolated node_modules) | 294 | FAIL (ENAMETOOLONG) |
| byte-identical robocopy /E /SL copy at a sibling path of the same length, junctions dereferenced | 0 | PASS |
| the same repository with node_modules moved aside, nothing else changed | 0 | PASS |
claude plugin eval <absolute path> run with cwd=C:\ still failed, so it depends on the plugin directory, not on the working directory or session state.
It is not MAX_PATH: a long-path enumeration (.NET, \\?\ prefix) found 23,509 files and none longer than 260 characters in either tree.
Threshold, by bisection with synthetic junctions
| each junction's own path length | last PASS (junction count) | first FAIL |
|---|---|---|
| ~90 chars | 36 | 37 |
| 199 chars | 17 | 18 |
Both flips land at roughly 3,400–3,600 characters of summed junction paths. The junctions' target length does not matter (151-char and 101-char targets both flipped at 37). The plugin root's own path length also shifts the budget.
On Windows, libuv returns UV_ENAMETOOLONG only when it translates ERROR_BUFFER_OVERFLOW or ERROR_FILENAME_EXCED_RANGE after CreateProcessW fails. That suggests something built from the directory listing (an environment block, a command line or a path list) grows past a limit. NODE_DEBUG=child_process printed nothing from the CLI, so I could not capture which field overflows.
Repro
- Create a minimal plugin with one eval case.
- Inside the plugin root, create ~40 directory junctions whose own paths are ~90 characters long (
mklink /J ...). - Run
claude plugin eval <plugin-dir> --runs 1. Expected: the case runs. Actual:ENAMETOOLONG: name too long, uv_spawn. - Remove the junctions and run again: it passes.
Workaround
node-linker=hoisted in .npmrc (pnpm's flat, npm-style layout: no junctions) makes the suite run. Plugins with a pnpm-managed node_modules in their root will hit this on Windows until eval stops walking or spawning with the junction set.