JuliusBrussee/caveman · error
cannot safely launch Windows command shim
Error message
cannot safely launch Windows command shim: ${executable} What it means
On Windows, `portableInvocation` in packages/pi-extension/src/portable-command.ts:84 safely wraps .cmd/.bat shims (to avoid spawning via cmd.exe). Before parsing a shim it stats the resolved executable and throws this Error if the path is not a regular file or exceeds 256 KiB — a guard against unsafe or corrupt command shims.
Solutions
- Reinstall the CLI whose shim is corrupt (`npm install -g <pkg>` or local reinstall) to regenerate a clean .cmd.
- Ensure the command resolves to the intended shim: check PATH order and remove shadowing directories/files.
- Prefer a native .exe binary for the command so the shim path is not taken at all.
Example fix
// before npm i -g some-cli // leaves a corrupt some-cli.cmd // after cache clean + reinstall npm cache clean --force && npm i -g some-cli
Defensive patterns
Strategy: fallback
Validate before calling
import { statSync } from 'node:fs';
function isLaunchableShim(p: string) {
try { const s = statSync(p); return s.isFile() && s.size <= 256 * 1024; } catch { return false; }
} Type guard
const isRegularFile = (p: string): boolean => { try { return statSync(p).isFile(); } catch { return false; } }; Try / catch
try {
const inv = portableInvocation(command, args, env);
} catch (e) {
if (e instanceof Error && /cannot safely launch Windows command shim/.test(e.message)) {
// fall back to a native binary or reinstall the tool
throw new Error(`Reinstall ${command} or provide a native .exe: ${e.message}`);
}
throw e;
} Prevention
- On Windows prefer native .exe binaries over .cmd shims.
- Keep PATH clean of directories shadowing command names.
- Reinstall tools whose shims look corrupt (0 bytes or unexpectedly huge).
When it happens
Trigger: Resolving a Windows command to a `.cmd`/`.bat` file that does not exist (statSync would throw ENOENT first) — practically: the shim path exists but is a directory, a device/special file, or a bloated (>256KB) file.
Common situations: A broken npm install leaving a corrupt or oversized .cmd shim; a directory named like a shim earlier on PATH; node_modules path shadowing.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- cannot safely launch non-Node Windows command shim
- Windows command shim target is missing
- file changed while opening
- inspect sqlite parent ACL
- sqlite parent grants broad Windows write access
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/c5a8faa28e21ec63.
Report an issue: GitHub.
Appendix: source
Thrown at packages/pi-extension/src/portable-command.ts:84
// Returns the command/args pair to hand to execFile/spawn. Non-win32 is a
// pass-through, so this is safe to route every invocation through.
//
// Fail-open by contract: the hook bridge treats a throw the same as a spawn
// error, and an unresolvable command falls through to the next candidate, so a
// shim we cannot parse must never take down the caller.
export function portableInvocation(
command: string,
args: readonly string[],
platform: NodeJS.Platform = process.platform,
env: NodeJS.ProcessEnv = process.env,
): PortableInvocation {
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 shimScript = parseWindowsNodeShim(readFileSync(executable, "utf8"));
if (!shimScript) {
throw new Error(`cannot safely launch non-Node Windows command shim: ${executable}; install a native .exe`);
}
const script = /^[A-Za-z]:[\\/]/.test(shimScript)
? shimScript
: resolve(dirname(executable), ...shimScript.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 3ee70a1026)