JuliusBrussee/caveman · error

Windows command shim target is missing: ${script}

Error message

Windows command shim target is missing: ${script}

What it means

After successfully parsing a Windows Node shim, caveman resolves the referenced script relative to the shim's directory and stats it. If the target .js file does not exist as a regular file, launching would fail cryptically later, so it throws this error naming the resolved absolute script path. It usually indicates a half-installed or moved package.

Source

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

export function portableInvocation(
  command: string,
  args: readonly string[],
  platform: NodeJS.Platform = process.platform,
): PortableInvocation {
  if (platform !== "win32" || !/\.(?:cmd|bat)$/i.test(command)) {
    return { command, args: [...args] };
  }
  const stat = statSync(command);
  if (!stat.isFile() || stat.size > 256 * 1024) {
    throw new Error(`cannot safely launch Windows command shim: ${command}`);
  }
  const relativeScript = parseWindowsNodeShim(readFileSync(command, "utf8"));
  if (!relativeScript) {
    throw new Error(`cannot safely launch non-Node Windows command shim: ${command}; install a native .exe`);
  }
  const script = resolve(dirname(command), ...relativeScript.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 27d5a3981a)

Solutions

  1. Reinstall the owning package so the shim's target script exists again (npm install / npm rebuild).
  2. Verify the path in the error: if the entry point moved (package upgrade renamed bin), regenerate shims via npm rebuild or by reinstalling.
  3. Remove the orphaned .cmd shim from PATH so resolution picks a working installation.

Example fix

# before: shim points at removed package
C:\proj\node_modules\.bin\tool.cmd  ->  ..\..\tool\bin.js (missing)
# after: reinstall to restore target
npm install tool
Defensive patterns

Strategy: try-catch

Validate before calling

import { existsSync, statSync } from "node:fs";
import { dirname, resolve } from "node:path";

function shimTargetExists(command: string, relativeScript: string): boolean {
  const target = resolve(dirname(command), ...relativeScript.split(/[\\/]+/));
  return existsSync(target) && statSync(target).isFile();
}

Try / catch

try {
  const invocation = portableInvocation(cmd, args);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Windows command shim target is missing")) {
    reinstallOwner(cmd); // npm install of the shim's package, then retry
    return portableInvocation(cmd, args);
  }
  throw e;
}

Prevention

When it happens

Trigger: portableInvocation on win32 where the .cmd shim parses and points to ..\node_modules\some-tool\bin.js (or similar), but statSync reports that path missing — deleted node_modules, partial install, or a copied shim without its package.

Common situations: Deleting node_modules while leaving global/local .bin shims behind, interrupted npm install, copying a project directory without node_modules, or package layout changes after an upgrade renaming the bin entry.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/4bd8098c73dc175a. Report an issue: GitHub.