Skip to content

node shim loops forever in system-first mode when the system node is a mise shim (vp and shell node hang) #2728

Description

@Stanzilla

Describe the bug

On a machine that also has mise installed (its shims dir is on PATH, but no Node version is activated for the current directory, so the mise node shim falls back to the system Node), the Vite+ node shim in system-first mode hangs forever at 100% CPU.

Effects:

  • Every JS-side vp command hangs with no output: vp migrate, vp migrate --help, vp help migrate, vp env current. Rust-only commands (vp help, vp --version, vp env doctor, vp toolchain) work.
  • Because ~/.config/vite-plus/env (sourced from .zshenv / .zshrc / .profile) prepends ~/.local/share/vite-plus/bin to PATH, a plain node --version in every new shell hangs as well. From the user's side this looks like "many commands just do nothing".

What happens (traced with ps, lsof and MISE_DEBUG=1):

  1. ~/.local/share/vite-plus/bin/node is a symlink to vp. In system-first mode it skips its own bin dir and picks the next node on PATH. vp env doctor confirms it resolves to the mise shim: System Node.js /Users/stan/.local/share/mise/shims/node.
  2. mise has no active Node for the directory, so its shim falls back to a PATH lookup. mise excludes its own shims dir, but not the Vite+ bin dir, which is first on PATH. It execs ~/.local/share/vite-plus/bin/node, which is vp again.
  3. The two shims exec each other forever. The hung process keeps the vp image name (lsof shows vp), and MISE_DEBUG=1 prints DEBUG config: ~/.config/mise/config.toml in an endless loop.

The recursion guard from #2157 (Recursion detected but no 'node' found in PATH) does not trigger here, presumably because the re-entry goes through mise and looks like a fresh invocation.

Expected: vp should detect that the "system" node resolves back to itself (for example by comparing the resolved target to its own shim path or inode, or with a marker that survives one exec through a foreign shim) and fall through to the next real node on PATH, or fail with the existing recursion error instead of spinning.

Secondary note: vp env off only switches the shims to system-first mode. The shim symlinks stay in ~/.local/share/vite-plus/bin and the env file keeps that dir first on PATH, so the loop above still happens after vp env off.

Evidence:

B=~/.local/share/vite-plus/bin

# works: Vite+ bin dir is not on PATH, shim finds mise shim, mise finds homebrew node
$ $B/node --version
v26.8.2

# hangs (killed by timeout after 10s): Vite+ bin dir first on PATH, as set up by ~/.config/vite-plus/env
$ PATH="$B:$PATH" timeout 10 $B/node --version; echo "exit=$?"
exit=124

# works again when mise shims are removed from PATH
$ P2=$(echo "$PATH" | tr ':' '\n' | grep -v mise/shims | paste -sd: -)
$ PATH="$B:$P2" $B/node --version
v26.8.2

# mise side of the loop
$ PATH="$B:$PATH" MISE_DEBUG=1 timeout 3 $B/node --version 2>&1 | head
DEBUG config: ~/.config/mise/config.toml
DEBUG EnvResults { env_paths: ["/Users/stan/.local/share/mise/command-wrappers/bin"] }
DEBUG config: ~/.config/mise/config.toml
DEBUG EnvResults { env_paths: ["/Users/stan/.local/share/mise/command-wrappers/bin"] }
...

Workaround: remove the mise shims dir from PATH when running vp, or vp env on node, or activate a global Node in mise (mise use -g node@<version>) so the mise shim stops falling back to PATH.

Reproduction

N/A (environment setup issue, steps below are a full reproduction on macOS)

Steps to reproduce

# 1. install mise, add its shims dir to PATH, install a node but do NOT activate it (no `mise use`)
brew install mise
echo 'export PATH="$HOME/.local/share/mise/shims:$PATH"' >> ~/.zshrc
mise install node@26

# 2. install Vite+ with the default shell setup (env file prepends ~/.local/share/vite-plus/bin), keep system-first mode
curl -fsSL https://viteplus.dev/install.sh | sh
vp env off

# 3. new shell
node --version          # hangs at 100% CPU
vp migrate --help       # hangs, no output
vp help migrate         # hangs, no output

System Info

$ vp env current   # (only prints with the PATH workaround above, otherwise it hangs)
Node.js:
  Version    26.8.2
  Source     system PATH
  Bin Path   /opt/homebrew/bin/node
  Installed  true
  Mode       system_first

Package Manager:
  Name       pnpm
  Version    10.33.4
  Source     system PATH
  Bin Paths
    pnpm     /Users/stan/.local/share/pnpm/bin/pnpm
    pnpx     /Users/stan/.local/share/pnpm/bin/pnpx
  Installed  true
  Mode       system_first

$ vp --version
vp v0.3.2

Local vite-plus:
  vite-plus  v0.3.2

Tools:
  vite             v8.3.0
  rolldown         v1.2.8
  vitest           v4.1.11
  oxfmt            v0.67.0
  oxlint           v1.82.0
  oxlint-tsgolint  v7.0.2001
  tsdown           v0.23.0

Environment:
  Package manager  pnpm v10.33.4
  Node.js          v24.21.0 (engines.node)

macOS 27.0 (arm64), zsh, mise 2026.9.9

$ vp env doctor (excerpt)
Configuration
  ✓ Node.js           system-first mode
  System Node.js    /Users/stan/.local/share/mise/shims/node
  ✓ Package manager   system-first mode
  ✓ IDE integration   env sourced in ~/.zshenv
PATH
  ✓ node              ~/.local/share/vite-plus/bin/node (vp shim)

Used Package Manager

pnpm

Logs

# hung child spawned by `vp migrate --help`, after 6s:
$ ps -o pid,%cpu,time,command -p <pid>
  PID  %CPU      TIME COMMAND
20531   0.0   0:05.50 /Users/stan/.local/share/vite-plus/bin/node /Users/stan/.local/share/vite-plus/0.3.2/node_modules/vite-plus/dist/bin.js migrate --help

$ lsof -p 20531 | head -1
vp      20531 stan ...        # image is vp, not node

# env of that child
VP_CLI_BIN=/Users/stan/.local/share/vite-plus/bin/vp
VP_PATH_INJECTED_TOOLS=node
PATH=/Users/stan/.local/share/vite-plus/bin:/Users/stan/.local/share/pnpm/bin:...:/Users/stan/.local/share/mise/shims:...

Validations

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

Priority

None yet

Effort

None yet

Target date

None yet

Start date

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions