Windows: agent-created node_modules junctions from git worktrees cause source-file deletion on worktree remove

Resolved 💬 3 comments Opened May 19, 2026 by danrichardson Closed May 27, 2026

Summary

During a ticket-chain run on Windows, the agent created Windows junctions to share node_modules between feature git worktrees and the main repo. When git worktree remove --force cleaned up the worktrees afterward, it followed the junctions recursively and deleted source files from the main repo's working tree.

All data was recoverable via git restore . (the commits had already been pushed), but the failure mode is silent and surprising.

What happened, step by step

  1. Main repo: C:\repo\securish-bike-parking - an npm-workspaces monorepo with apps/api, apps/web, packages/contracts
  2. Agent created 4 feature worktrees at sibling paths (../wt-bkfk2-57, etc.) from main
  3. Agent created Windows junctions so the worktrees could share the main repo's node_modules (to avoid re-running npm install four times):

``
cmd //c mklink //J "C:\repo\wt-bkfk2-57\node_modules" "C:\repo\securish-bike-parking\node_modules"
``

  1. Agent implemented tickets in the worktrees, committed, merged each branch to main, pushed
  2. Agent removed each worktree:

``
git worktree remove --force /c/repo/wt-bkfk2-57
``

  1. On Windows, git's worktree removal uses recursive directory deletion that follows junctions (analogous to rmdir /S /Q). The chain was:
  • Delete wt-bkfk2-57\node_modules → this is a junction → follows into securish-bike-parking\node_modules
  • Inside securish-bike-parking\node_modules\@bkfk2\api → npm workspace junction → follows into ../../apps/api
  • Result: securish-bike-parking\apps\api\ contents deleted

Why the npm workspace chain exists

npm workspaces on Windows creates junctions (not POSIX symlinks) for workspace packages. So node_modules/@bkfk2/api is a Windows junction pointing to ../../apps/api. Any recursive delete that follows junctions will traverse from node_modules → workspace source directories.

Impact

Source files under apps/api/, most of apps/web/, and packages/contracts/ were wiped from the working tree. Files that the merges had just written back (App.tsx, identity.ts, etc.) were the only survivors. git restore . recovered everything cleanly since the code was in the index.

Guidance requested

The agent chose this junction approach to avoid the cost of four parallel npm install runs. That tradeoff is reasonable in intent, but the Windows junction-following behavior made it catastrophic.

Two things would prevent this:

  1. Agent-side: never create a Windows junction from a feature worktree that points into the main repo's node_modules. Safer alternatives: npm install per worktree (npm cache makes it fast), or copy / reference node_modules with a plain path env var rather than a filesystem junction.
  1. Tooling-side: if Claude Code's worktree-removal path on Windows can detect that a directory being removed contains a junction pointing outside the worktree's own tree, it could warn or refuse rather than silently following the junction into the parent repo.

Environment

  • Windows 11 Pro
  • Git for Windows / MSYS2 Bash
  • npm workspaces monorepo
  • Claude Code agent running the /tch (ticket-chain) skill

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗