JuliusBrussee/caveman · error · Error

Windows command shim target is missing

Error message

Windows command shim target is missing: ${script}

What it means

Thrown by portableInvocation() on Windows when the Node shim embedded in a .cmd/.bat points to a script file that does not exist: parseWindowsNodeShim extracted the target path, it was resolved (absolute, or relative to the shim's directory), but statSync(script).isFile() fails. This indicates a broken or partially uninstalled package whose shim survived while its entry script was removed.

Solutions

  1. Reinstall the package globally: `npm install -g <package>` to regenerate shim + target script.
  2. Check the referenced script path in the error; restore the missing file or fix npm's global prefix (`npm config get prefix`).
  3. Align node version managers (nvm/fnm/volta) so the shim's target exists under the active node install.
  4. Remove stale shims from the global bin directory for packages you no longer use.

Example fix

// before
C:\Users\me\AppData\Roaming\npm\oldtool.cmd -> ..\lib\node_modules\oldtool\cli.js (missing) // throws
// after
npm install -g oldtool   // regenerates shim and cli.js
invocation("oldtool")    // spawns: node ...\oldtool\cli.js
Defensive patterns

Strategy: validation

Validate before calling

import { statSync, existsSync } from "fs";
function shimTargetExists(shimPath: string): boolean {
  try {
    const content = readFileSync(shimPath, "utf8");
    const m = content.match(/"%~dp0\\\\?([^\"]+\.js)"/i) || content.match(/node[^\r\n]*?([\w.\\/-]+\.js)/i);
    if (!m) return true; // not a node shim; other errors apply
    const target = require("path").resolve(require("path").dirname(shimPath), m[1]);
    return existsSync(target) && statSync(target).isFile();
  } catch { return false; }
}

Try / catch

try {
  const inv = invocation(cmd, args);
  spawn(inv.command, inv.args);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Windows command shim target is missing")) {
    console.error("Broken install: run `npm install -g <pkg>` to regenerate the shim target", e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: platform === 'win32', command resolves to a valid small Node .cmd shim, the extracted script path resolves to a non-existent or non-file location (package uninstalled, node_modules pruned, drive letter changed, wrong global prefix).

Common situations: node_modules partially deleted while global prefix shims remain, switching nvm/node versions so the shim references a removed install, or moving/copying an npm global directory without its target layout.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/4bd8098c73dc175a. Report an issue: GitHub.

Appendix: source

Thrown at packages/cli/src/portable-command.ts:75

  platform: NodeJS.Platform = process.platform,
  env: NodeJS.ProcessEnv = process.env,
): PortableInvocation {
  if (platform !== "win32") return { command, args: [...args] };
  const executable = resolveWindowsCommand(command, env) ?? command;
  if (!/\.(?:cmd|bat)$/i.test(executable)) return { command: executable, args: [...args] };
  const stat = statSync(executable);
  if (!stat.isFile() || stat.size > 256 * 1024) {
    throw new Error(`cannot safely launch Windows command shim: ${executable}`);
  }
  const shimScript = parseWindowsNodeShim(readFileSync(executable, "utf8"));
  if (!shimScript) {
    throw new Error(`cannot safely launch non-Node Windows command shim: ${executable}; install a native .exe`);
  }
  const script = /^[A-Za-z]:[\\/]/.test(shimScript)
    ? shimScript
    : resolve(dirname(executable), ...shimScript.split(/[\\/]+/));
  if (!statSync(script).isFile()) {
    throw new Error(`Windows command shim target is missing: ${script}`);
  }
  return { command: process.execPath, args: [script, ...args] };
}

View on GitHub (pinned to 3ee70a1026)