JuliusBrussee/caveman · error
unsafe Windows command shim: ${executable}
Error message
unsafe Windows command shim: ${executable} What it means
portableInvocation() in agents/delegate/portable-process.mjs rejects a .cmd/.bat shim on Windows when statSync shows it is not a regular file or exceeds 256 KiB. A shim that large or non-file does not match any legitimate npm-generated launcher, so the safe-spawn machinery treats it as untrusted input rather than executing it.
Source
Thrown at agents/delegate/portable-process.mjs:34
? [command]
: pathExt.split(";").map((extension) =>
`${command}${extension.startsWith(".") ? extension : `.${extension}`}`);
for (const directory of (envValue(env, "PATH") ?? "").split(";")) {
if (!directory) continue;
for (const name of names) {
const candidate = join(directory, name);
if (existsSync(candidate)) return candidate;
}
}
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,
};
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Check the printed path: file type, size, and content — if you did not write it, treat it as suspect
- Clear the package manager cache and reinstall the package that owns the shim (npm cache clean plus fresh install)
- If the shim is legitimate but oversized, replace it with a direct node invocation on the real JS entrypoint
Example fix
# before where npx # points at a 2MB .bat # after del "C:\\path\\to\\suspect.bat" && npm install # or bypass: node .\\node_modules\\pkg\\bin\\cli.js
Defensive patterns
Strategy: type-guard
Validate before calling
const fs = require("node:fs");
function isSafeShim(p) {
try {
const st = fs.statSync(p);
return st.isFile() && st.size <= 256 * 1024;
} catch { return false; }
} Type guard
function isTrustableCmdShim(executablePath) {
if (!/\.(?:cmd|bat)$/i.test(executablePath)) return false;
let st;
try { st = fs.statSync(executablePath); } catch { return false; }
return st.isFile() && st.size <= 256 * 1024;
} Try / catch
if (!isTrustableCmdShim(cmd)) { spawn(process.execPath, [jsEntry, ...args]); return; }
try { spawn(...getSpawnInvocation(cmd, args)); }
catch (e) { /* reinstall the owning package */ } Prevention
- Inspect any .cmd or .bat you did not generate before it lands on PATH ahead of your tools
- Keep the npm cache clean; corrupted caches produce oversized garbage shims
- Treat an oversized shim as a security signal, not an inconvenience
When it happens
Trigger: The resolved .cmd/.bat is a directory, a symlink or pipe, or a batch file over 256 KiB — a corrupted download, a data file misnamed .bat, or an intentionally bloated script placed on PATH.
Common situations: Corrupted npm cache producing garbage shims; PATH pollution where another program's oversized .bat shadows the intended command; malicious or hand-rolled batch scripts; filesystem damage after disk-full events.
Related errors
- cannot safely launch non-Node Windows command shim: ${execut
- Windows command shim target is missing: ${script}
- non-Node Windows command shim: ${executable}
- Windows command shim target missing: ${script}
- cannot safely launch Windows command shim: ${executable}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/f205988b394d34fe.
Report an issue: GitHub.