JuliusBrussee/caveman · error
cannot safely launch non-Node Windows command shim: ${comman
Error message
cannot safely launch non-Node Windows command shim: ${command}; install a native .exe What it means
When caveman launches a Windows .cmd/.bat shim it parses the shim text to find the Node script it delegates to, then runs that script with process.execPath — it never executes the batch file through cmd.exe. If parseWindowsNodeShim cannot find a recognizable Node script reference inside the shim, it throws this error with the remediation of installing a native .exe. Supported shims are the standard npm/yarn/pnpm-style Node launchers.
Source
Thrown at packages/cli/src/portable-command.ts:29
}
return null;
}
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
- Install a native .exe build of the tool and let caveman resolve that instead of the .cmd.
- If the target is Node after all, rewrite the .cmd as a standard npm-style shim (a short batch file that runs node with the adjacent .js entry) so the parser can find the script.
- Pass the underlying .js entry (or node script path) directly so no shim parsing is involved.
Example fix
:: before: arbitrary batch logic @echo off some-tool --raw %* :: after: standard node shim caveman can parse @echo off node "%~dp0\some-tool.js" %*
Defensive patterns
Strategy: type-guard
Validate before calling
import { readFileSync } from "node:fs";
// Mirror of the npm-style shim shapes the parser accepts
const SHIM_RE = /(?:node|"?[^"]*node\.exe"?)\s+"?%~dp0[\\/]?([^"\r\n%]+\.js)/i;
function isNodeShim(command: string): boolean {
try { return SHIM_RE.test(readFileSync(command, "utf8")); } catch { return false; }
} Try / catch
try {
const invocation = portableInvocation(cmd, args);
} catch (e) {
if (e instanceof Error && e.message.includes("install a native .exe")) {
throw new ConfigError(`Replace custom batch wrapper ${cmd} with a native .exe or a standard node shim`);
}
throw e;
} Prevention
- Use standard npm-generated shims; do not hand-write batch launchers for tools caveman spawns.
- Install .exe builds of tools on Windows wherever available.
- If a batch wrapper is required, keep it a thin `node "%~dp0\entry.js" %*` line the parser recognizes.
When it happens
Trigger: portableInvocation on win32 with a .cmd/.bat that passes the size check but whose contents are not a recognizable Node shim — e.g. a batch file doing arbitrary logic, SET/IF blocks, or calling a non-Node binary.
Common situations: Custom .bat wrappers around tools, shims generated by Python/pip (pip.exe launchers) or other non-Node ecosystems, hand-written batch launchers on PATH that caveman discovers, or an edited npm shim whose node invocation line was altered.
Related errors
- cannot safely launch Windows command shim: ${command}
- Windows command shim target is missing: ${script}
- cannot safely launch Windows command shim: ${executable}
- cannot safely launch non-Node Windows command shim: ${execut
- cannot safely launch non-Node Windows command shim: ${execut
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/ec776898497fff70.
Report an issue: GitHub.