JuliusBrussee/caveman · error
Windows command shim target missing: ${script}
Error message
Windows command shim target missing: ${script} What it means
portableInvocation() resolved the Node script that a Windows .cmd/.bat shim forwards to, but statSync says that target is not an existing file. The safe-spawn path will not fall back to executing the raw batch file, so it fails fast with the resolved absolute script path in the message.
Source
Thrown at agents/delegate/portable-process.mjs:43
}
return null;
}
export function portableInvocation(command, args, platform = process.platform, env = process.env) {
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(`unsafe Windows command shim: ${executable}`);
let relativeScript = null;
for (const line of readFileSync(executable, "utf8").split(/\r?\n/)) {
if (!/(?:\bnode(?:\.exe)?\b|_prog)/i.test(line) || !/%\*/.test(line)) continue;
const match = line.match(/"%(?:dp0%|~dp0)\\([^"\r\n]+\.(?:cjs|mjs|js))"\s+%\*/i);
if (match) { relativeScript = match[1]; break; }
}
if (!relativeScript) throw new Error(`non-Node Windows command shim: ${executable}`);
const script = resolve(dirname(executable), ...relativeScript.split(/[\\/]+/));
if (!statSync(script).isFile()) throw new Error(`Windows command shim target missing: ${script}`);
return { command: process.execPath, args: [script, ...args] };
}
export function delegateSpawnOptions(platform = process.platform) {
return {
detached: platform !== "win32",
windowsHide: true,
};
}
export async function killProcessTree(
child,
platform = process.platform,
taskkill = spawnSync,
kill = process.kill,
graceMs = 1500,
) {
if (!child?.pid) return;View on GitHub (pinned to 27d5a3981a)
Solutions
- Do a clean reinstall of the package owning the shim (rm -rf node_modules plus a lockfile-exact install)
- Check the printed absolute path — if it looks truncated or wrong-shaped, fix PATH length or Long Paths settings and reinstall
- Invoke the real entrypoint with node directly, bypassing the shim
Example fix
# before # Windows command shim target missing: C:\proj\node_modules\.bin\..\foo\dist\cli.js # after npm ci # clean, lockfile-exact reinstall restores the target file
Defensive patterns
Strategy: fallback
Validate before calling
// before spawn: probe the shim's forwarded target const ok = shimTargetExists(cmd); // see error 464 validationCode if (!ok) await cleanReinstall(pkg);
Try / catch
try { spawn(inv.command, inv.args); }
catch (e) {
if (/shim target (?:is )?missing/.test(String(e?.message))) { await reinstall(pkg); }
else throw e;
} Prevention
- Use lockfile-exact installs (npm ci) in CI and locally
- Re-run install after any tool prunes node_modules
When it happens
Trigger: A stale or half-installed package: the .bin shim exists but the JS entrypoint it points to was deleted, moved, or never extracted; broken %~dp0 resolution after node_modules was relocated.
Common situations: Interrupted installs; aggressive node_modules cleaners (npkill, dedupe tools); monorepo hoisting moving the package while leaving the workspace .bin shim; Windows path-length limits truncating extraction.
Related errors
- Windows command shim target is missing: ${script}
- unsafe Windows command shim: ${executable}
- cannot safely launch non-Node Windows command shim: ${execut
- Windows command shim target is missing: ${script}
- cannot safely launch non-Node Windows command shim: ${execut
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/23b9cde518a44fdf.
Report an issue: GitHub.