JuliusBrussee/caveman · error
cannot safely launch Windows command shim: ${executable}
Error message
cannot safely launch Windows command shim: ${executable} What it means
Thrown by portableProcessInvocation() on win32 when the resolved command is a .cmd/.bat shim but statSync shows it is not a regular file or exceeds 256 KB. The size cap is a safety guard: real npm/node shim launchers are tiny, and an oversized or non-file path is a sign the resolver found something it should not execute (or a PATH entry pointing at a directory or device with the same name).
Source
Thrown at packages/subagent-tax/lib/process-tree.mjs:49
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) return match[1];
}
return null;
}
export function portableProcessInvocation(
command,
args,
{ platform = process.platform, env = process.env, execPath = process.execPath } = {},
) {
if (platform !== "win32") return { command, args: [...args] };
const executable = resolveWindowsCommand(command, env);
if (!executable) throw Object.assign(new Error(`command not found: ${command}`), { code: "ENOENT" });
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 relativeScript = parseWindowsNodeShim(readFileSync(executable, "utf8"));
if (!relativeScript) {
throw new Error(`cannot safely launch non-Node Windows command shim: ${executable}`);
}
const script = resolve(dirname(executable), ...relativeScript.split(/[\\/]+/));
if (!statSync(script).isFile()) throw new Error(`Windows command shim target is missing: ${script}`);
return { command: execPath, args: [script, ...args] };
}
export function harnessSpawnOptions(platform = process.platform) {
return {
detached: platform !== "win32",
windowsHide: true,
};
}
export function forceKillTree(View on GitHub (pinned to 27d5a3981a)
Solutions
- Inspect the resolved shim path named in the error: check `dir <path>` and the file size.
- If it is an oversized or foreign script, remove it from PATH precedence or reinstall the package that owns it (e.g. `npm reinstall` / clear node_modules and reinstall).
- If you control the wrapper, pass the absolute path to the real Node script (or the underlying .exe) directly instead of going through the shim.
Example fix
// before
const inv = portableProcessInvocation("my-tool", [], { platform: "win32" }); // shim resolves to 900KB wrapper.bat
// after
const inv = portableProcessInvocation("C:/proj/node_modules/.bin/my-tool.cmd", [], { platform: "win32" }); // point at the genuine small npm shim Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from "node:fs";
function isSafeShim(executable) {
try {
const st = statSync(executable);
return st.isFile() && st.size <= 256 * 1024;
} catch { return false; }
} Try / catch
try {
const inv = portableProcessInvocation(cmd, args, { platform: "win32" });
} catch (err) {
if (/cannot safely launch Windows command shim/.test(err.message)) {
// fall back to invoking the real executable path directly
} else throw err;
} Prevention
- Point at the real .exe or Node script instead of .cmd shims when you control the path.
- Reinstall packages whose shims look corrupted or oversized before running.
When it happens
Trigger: Calling portableProcessInvocation with platform win32 where PATH resolution lands on a .cmd/.bat that is actually a directory symlink target, a special file, or a large batch script (e.g. someone shipped a 1 MB self-extracting batch wrapper).
Common situations: A corrupted npm install produced a bloated .cmd shim; a PATH directory contains a same-named .bat that is a launcher for something else entirely; antivirus or a sync tool replaced the shim with a stub.
Related errors
- cannot safely launch non-Node Windows command shim: ${execut
- cannot safely launch non-Node Windows command shim: ${execut
- unsafe Windows command shim: ${executable}
- non-Node Windows command shim: ${executable}
- Windows command shim target is missing: ${script}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/1b19e490782dca24.
Report an issue: GitHub.