{"record":{"id":"ec776898497fff70","repo":"JuliusBrussee/caveman","slug":"cannot-safely-launch-non-node-windows-command-shim-ec7768","errorCode":null,"errorMessage":"cannot safely launch non-Node Windows command shim: ${command}; install a native .exe","messagePattern":"cannot safely launch non-Node Windows command shim: (.+?); install a native \\.exe","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/portable-command.ts","lineNumber":29,"sourceCode":"  }\n  return null;\n}\n\nexport function portableInvocation(\n  command: string,\n  args: readonly string[],\n  platform: NodeJS.Platform = process.platform,\n): PortableInvocation {\n  if (platform !== \"win32\" || !/\\.(?:cmd|bat)$/i.test(command)) {\n    return { command, args: [...args] };\n  }\n  const stat = statSync(command);\n  if (!stat.isFile() || stat.size > 256 * 1024) {\n    throw new Error(`cannot safely launch Windows command shim: ${command}`);\n  }\n  const relativeScript = parseWindowsNodeShim(readFileSync(command, \"utf8\"));\n  if (!relativeScript) {\n    throw new Error(`cannot safely launch non-Node Windows command shim: ${command}; install a native .exe`);\n  }\n  const script = resolve(dirname(command), ...relativeScript.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":11,"sourceCodeEnd":37,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/portable-command.ts#L11-L37","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":":: before: arbitrary batch logic\n@echo off\nsome-tool --raw %*\n:: after: standard node shim caveman can parse\n@echo off\nnode \"%~dp0\\some-tool.js\" %*","handlingStrategy":"type-guard","validationCode":"import { readFileSync } from \"node:fs\";\n\n// Mirror of the npm-style shim shapes the parser accepts\nconst SHIM_RE = /(?:node|\"?[^\"]*node\\.exe\"?)\\s+\"?%~dp0[\\\\/]?([^\"\\r\\n%]+\\.js)/i;\nfunction isNodeShim(command: string): boolean {\n  try { return SHIM_RE.test(readFileSync(command, \"utf8\")); } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const invocation = portableInvocation(cmd, args);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"install a native .exe\")) {\n    throw new ConfigError(`Replace custom batch wrapper ${cmd} with a native .exe or a standard node shim`);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["windows","shim","cli","security"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}