JuliusBrussee/caveman · error · Error
cannot safely launch non-Node Windows command shim: ${execut
Error message
cannot safely launch non-Node Windows command shim: ${executable} What it means
After a Windows .cmd/.bat shim passes the size and file-type checks, the library parses its contents to confirm it is a Node shim (the standard npm-generated wrapper that forwards to a target .js file). Only verified Node shims are safe to relaunch via process.execPath, because executing arbitrary batch content would allow command injection. If the shim body does not match the known Node-shim shape, it throws 'cannot safely launch non-Node Windows command shim'.
Source
Thrown at packages/agent/src/portable-process.ts:60
args: readonly string[],
options: {
platform?: NodeJS.Platform;
env?: NodeJS.ProcessEnv;
execPath?: string;
} = {},
): PortableInvocation {
const platform = options.platform ?? process.platform;
const env = options.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(`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: options.execPath ?? process.execPath, args: [script, ...args] };
}
export function hostShellInvocation(
source: string,
platform: NodeJS.Platform = process.platform,
env: NodeJS.ProcessEnv = process.env,
): PortableInvocation {
if (platform === "win32") {
return {
command: envValue(env, "ComSpec") ?? "cmd.exe",
args: ["/d", "/s", "/c", source],
};
}
return { command: "/bin/sh", args: ["-c", source] };View on GitHub (pinned to 27d5a3981a)
Solutions
- Replace the custom .cmd with an npm-style Node shim, or invoke node <script.js> directly and skip the .cmd entirely
- Pin/align the package manager so shims are generated in the recognized format
- Check PATH resolution: resolveWindowsCommand may be finding a different .cmd than you expect (where <command> in cmd.exe)
- For non-Node CLIs, spawn via an explicit shell invocation (hostShellInvocation) rather than the portable path
Example fix
// before
const inv = portableInvocation("build-tool", args); // build-tool.cmd is a hand-written batch script
// after
const inv = portableInvocation(process.execPath, ["./tools/build-tool.js", ...args]); Defensive patterns
Strategy: fallback
Try / catch
try {
const inv = portableInvocation(cmd, args);
} catch (e) {
if (e instanceof Error && e.message.includes("non-Node Windows command shim")) {
// fallback: invoke the underlying script or an explicit shell command
return hostShellInvocation(`${cmd} ${args.join(" ")}`, "win32", env);
}
throw e;
} Prevention
- Do not hand-write .cmd wrappers for node CLIs; let a package manager generate shims
- Standardize one package manager per repo so shim format stays consistent
- When wrapping external non-node tools, route through hostShellInvocation deliberately
When it happens
Trigger: A .cmd/.bat that is a hand-written batch script (if/for/set logic) rather than an npm Node shim, a shim format from a different tool (pnpm/yarn generate different wrappers unless recognized), or an edited/obfuscated shim whose target line no longer parses.
Common situations: Team ships a custom .cmd wrapper for an internal CLI, a package manager upgrade changed shim generation format, or the command name collides with a system batch file found earlier on PATH.
Related errors
- cannot safely launch Windows command shim: ${executable}
- Windows command shim target is missing: ${script}
- cannot safely launch Windows command shim: ${command}
- cannot safely launch non-Node Windows command shim: ${comman
- cannot safely launch non-Node Windows command shim: ${execut
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/0638a2a8ecc80289.
Report an issue: GitHub.