{"record":{"id":"c5a8faa28e21ec63","repo":"JuliusBrussee/caveman","slug":"cannot-safely-launch-windows-command-shim-executable-c5a8fa","errorCode":null,"errorMessage":"cannot safely launch Windows command shim: ${executable}","messagePattern":"cannot safely launch Windows command shim: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/pi-extension/src/portable-command.ts","lineNumber":84,"sourceCode":"\n// Returns the command/args pair to hand to execFile/spawn. Non-win32 is a\n// pass-through, so this is safe to route every invocation through.\n//\n// Fail-open by contract: the hook bridge treats a throw the same as a spawn\n// error, and an unresolvable command falls through to the next candidate, so a\n// shim we cannot parse must never take down the caller.\nexport function portableInvocation(\n  command: string,\n  args: readonly string[],\n  platform: NodeJS.Platform = process.platform,\n  env: NodeJS.ProcessEnv = process.env,\n): PortableInvocation {\n  if (platform !== \"win32\") return { command, args: [...args] };\n  const executable = resolveWindowsCommand(command, env) ?? command;\n  if (!/\\.(?:cmd|bat)$/i.test(executable)) return { command: executable, args: [...args] };\n  const stat = statSync(executable);\n  if (!stat.isFile() || stat.size > 256 * 1024) {\n    throw new Error(`cannot safely launch Windows command shim: ${executable}`);\n  }\n  const shimScript = parseWindowsNodeShim(readFileSync(executable, \"utf8\"));\n  if (!shimScript) {\n    throw new Error(`cannot safely launch non-Node Windows command shim: ${executable}; install a native .exe`);\n  }\n  const script = /^[A-Za-z]:[\\\\/]/.test(shimScript)\n    ? shimScript\n    : resolve(dirname(executable), ...shimScript.split(/[\\\\/]+/));\n  if (!statSync(script).isFile()) {\n    throw new Error(`Windows command shim target is missing: ${script}`);\n  }\n  return { command: process.execPath, args: [script, ...args] };\n}\n","sourceCodeStart":66,"sourceCodeEnd":98,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/pi-extension/src/portable-command.ts#L66-L98","documentation":"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.","triggerScenarios":"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.","commonSituations":"A broken npm install leaving a corrupt or oversized .cmd shim; a directory named like a shim earlier on PATH; node_modules path shadowing.","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."],"exampleFix":"// before\nnpm i -g some-cli   // leaves a corrupt some-cli.cmd\n// after\ncache clean + reinstall\nnpm cache clean --force && npm i -g some-cli","handlingStrategy":"fallback","validationCode":"import { statSync } from 'node:fs';\nfunction isLaunchableShim(p: string) {\n  try { const s = statSync(p); return s.isFile() && s.size <= 256 * 1024; } catch { return false; }\n}","typeGuard":"const isRegularFile = (p: string): boolean => { try { return statSync(p).isFile(); } catch { return false; } };","tryCatchPattern":"try {\n  const inv = portableInvocation(command, args, env);\n} catch (e) {\n  if (e instanceof Error && /cannot safely launch Windows command shim/.test(e.message)) {\n    // fall back to a native binary or reinstall the tool\n    throw new Error(`Reinstall ${command} or provide a native .exe: ${e.message}`);\n  }\n  throw e;\n}","preventionTips":["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)."],"tags":["windows","command-shim","filesystem","launch"],"backgroundTag":"unsupported-platform","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}