{"record":{"id":"fd55fd9df74365a6","repo":"JuliusBrussee/caveman","slug":"cannot-safely-launch-non-node-windows-command-shim-portable","errorCode":null,"errorMessage":"cannot safely launch non-Node Windows command shim: ${executable}; install a native .exe","messagePattern":"cannot safely launch non-Node Windows command shim: (.+?); install a native \\.exe","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/portable-command.ts","lineNumber":69,"sourceCode":"  return undefined;\n}\n\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":51,"sourceCodeEnd":79,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/portable-command.ts#L51-L79","documentation":"Thrown by portableInvocation() on Windows when a .cmd/.bat shim passes the size/file checks but its contents are not a recognizable Node shim (parseWindowsNodeShim returns null). The library will not execute arbitrary batch shims; it demands either a native .exe or a shim whose embedded script points at a Node entry it can launch with process.execPath. This avoids executing untrusted batch logic with user-supplied args.","triggerScenarios":"platform === 'win32', the resolved command ends in .cmd/.bat, and reading the file yields content that parseWindowsNodeShim cannot interpret as a Node launcher shim (e.g. a plain batch script, not the standard npm/node shim format).","commonSituations":"Third-party tools shipping hand-written .cmd wrappers, corporate wrapper scripts around real binaries, globally-installed tools whose shims were customized or corrupted, or a text file coincidentally named .cmd on PATH.","solutions":["Install a native .exe build of the command (vendor installer, winget, scoop) and ensure it wins on PATH.","Replace the custom .cmd wrapper with the standard npm-generated Node shim by reinstalling the package.","Invoke the target directly: `node path\\to\\cli.js` for Node tools, bypassing the shim.","Remove the unknown .cmd from PATH if it is not the tool you intend to run."],"exampleFix":"// before\ninvocation(\"mytool\") // mytool resolves to custom mytool.cmd batch script -> throws\n// after\n// install native binary:\nwinget install mytool\ninvocation(\"mytool\") // resolves to mytool.exe -> spawns directly","handlingStrategy":"validation","validationCode":"import { readFileSync, statSync } from \"fs\";\nfunction looksLikeNodeShim(p: string): boolean {\n  if (!/\\.(?:cmd|bat)$/i.test(p)) return true;\n  try {\n    const content = readFileSync(p, \"utf8\");\n    return /node/i.test(content) && /%~dp0|node_modules/.test(content); // standard npm shim markers\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const inv = invocation(cmd, args);\n  spawn(inv.command, inv.args);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"non-Node Windows command shim\")) {\n    console.error(\"Custom .cmd wrapper rejected; install the native .exe or run node <cli.js> directly\");\n  } else throw e;\n}","preventionTips":["Install native .exe builds of tools on Windows","Avoid hand-edited .cmd wrappers for CLI tools","Reinstall packages to restore standard npm-generated shims","Run Node CLIs via `node path/to/cli.js` to bypass shim parsing entirely"],"tags":["windows","spawn","security","shim"],"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"}