Skip to content

Windows: deferred implode cleanup leaves payloads with paths over 260 characters #2502

Description

@fengmk2

Summary

On Windows PowerShell 5.1, vp implode --yes can permanently leave a renamed
data.removing-<PID> directory when the installed dependency tree contains
paths longer than 260 characters.

This was discovered while testing #2346, but should be handled as follow-up
work rather than expanding that PR.

Current behavior

vp implode:

  1. Renames the data root to data.removing-<PID>.
  2. Starts a detached PowerShell process to delete the renamed root.
  3. Exits successfully and reports that removal was scheduled.

The deferred script recursively uses Get-Item, Get-ChildItem, and .NET
File/Directory deletion APIs. PowerShell 5.1 cannot directly reopen some
over-260-character paths. The script retries the same operation 100 times and
then exits without notifying the already-finished vp implode process.

The original data path is available for reinstall, but the old dependency tree
remains on disk.

Example

The failure reproduced with this 280-character path:

C:\Users\fengmk2\AppData\Local\Temp\v556\scenario-10-implode\profile\AppData\Local\vite-plus\data.removing-13596\pkg-pr-new-2346\node_modules\.pnpm\@vitest+browser@4.1.10_vite@8.2.1_vitest@4.1.10\node_modules\@vitest\browser\dist\client\__vitest_browser__\orchestrator-KVYrTcFi.js

Direct lookup under Windows PowerShell 5.1 fails:

Get-Item -LiteralPath $LongPath
# Cannot find path ... because it does not exist.

The file can still be discovered while enumerating its parent directory.

When it occurs

This is most likely with:

  • A custom VP_DATA_DIR or VP_HOME under a deeply nested workspace.
  • Redirected %LOCALAPPDATA%.
  • Long corporate profile or OneDrive paths.
  • CI environments that create an isolated user profile under the workspace.
  • pnpm virtual-store paths containing package, version, and peer-dependency names.

A normal short default Windows profile passed the same full-payload cleanup.

Reproduction requirements

  1. Use Windows PowerShell 5.1.
  2. Install Vite+ with full dependencies; do not use VP_SKIP_DEPS_INSTALL.
  3. Choose a nested data or monolithic root.
  4. Confirm at least one installed path exceeds 260 characters.
  5. Run vp implode --yes.
  6. Wait for the deferred cleanup process.
  7. Check for sibling *.removing-* directories.

Expected behavior

All Vite+-owned roots are removed, or an actionable cleanup failure is
reported. No permanent *.removing-* directory remains.

Suggested direction

Use a long-path-aware native Windows cleanup helper instead of PowerShell 5.1
recursive deletion.

The helper should:

  • Use extended-length paths or wide Win32 filesystem APIs.
  • Delete reparse points without traversing their targets.
  • Wait for the original vp.exe process to exit.
  • Operate only on the uniquely renamed root.
  • Preserve an immediately reinstalled replacement.
  • Retry sharing violations for a bounded period.
  • Record an actionable failure if cleanup still cannot complete.

Acceptance tests

  • Full dependency installation with an asserted path length over 260 characters.
  • Split and monolithic implode.
  • Temporarily locked files and dangling pnpm junctions.
  • Immediate reinstall after implode.
  • No remaining *.removing-* roots.
  • Replacement installation remains usable.
  • Unrelated files in a shared custom bin remain untouched.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions