{"record":{"id":"1b19e490782dca24","repo":"JuliusBrussee/caveman","slug":"cannot-safely-launch-windows-command-shim-execu-1b19e4","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/subagent-tax/lib/process-tree.mjs","lineNumber":49,"sourceCode":"    if (!/(?:\\bnode(?:\\.exe)?\\b|_prog)/i.test(line) || !/%\\*/.test(line)) continue;\n    const match = line.match(/\"%(?:dp0%|~dp0)\\\\([^\"\\r\\n]+\\.(?:cjs|mjs|js))\"\\s+%\\*/i);\n    if (match) return match[1];\n  }\n  return null;\n}\n\nexport function portableProcessInvocation(\n  command,\n  args,\n  { platform = process.platform, env = process.env, execPath = process.execPath } = {},\n) {\n  if (platform !== \"win32\") return { command, args: [...args] };\n  const executable = resolveWindowsCommand(command, env);\n  if (!executable) throw Object.assign(new Error(`command not found: ${command}`), { code: \"ENOENT\" });\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 relativeScript = parseWindowsNodeShim(readFileSync(executable, \"utf8\"));\n  if (!relativeScript) {\n    throw new Error(`cannot safely launch non-Node Windows command shim: ${executable}`);\n  }\n  const script = resolve(dirname(executable), ...relativeScript.split(/[\\\\/]+/));\n  if (!statSync(script).isFile()) throw new Error(`Windows command shim target is missing: ${script}`);\n  return { command: execPath, args: [script, ...args] };\n}\n\nexport function harnessSpawnOptions(platform = process.platform) {\n  return {\n    detached: platform !== \"win32\",\n    windowsHide: true,\n  };\n}\n\nexport function forceKillTree(","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/subagent-tax/lib/process-tree.mjs#L31-L67","documentation":"Thrown by portableProcessInvocation() on win32 when the resolved command is a .cmd/.bat shim but statSync shows it is not a regular file or exceeds 256 KB. The size cap is a safety guard: real npm/node shim launchers are tiny, and an oversized or non-file path is a sign the resolver found something it should not execute (or a PATH entry pointing at a directory or device with the same name).","triggerScenarios":"Calling portableProcessInvocation with platform win32 where PATH resolution lands on a .cmd/.bat that is actually a directory symlink target, a special file, or a large batch script (e.g. someone shipped a 1 MB self-extracting batch wrapper).","commonSituations":"A corrupted npm install produced a bloated .cmd shim; a PATH directory contains a same-named .bat that is a launcher for something else entirely; antivirus or a sync tool replaced the shim with a stub.","solutions":["Inspect the resolved shim path named in the error: check `dir <path>` and the file size.","If it is an oversized or foreign script, remove it from PATH precedence or reinstall the package that owns it (e.g. `npm reinstall` / clear node_modules and reinstall).","If you control the wrapper, pass the absolute path to the real Node script (or the underlying .exe) directly instead of going through the shim."],"exampleFix":"// before\nconst inv = portableProcessInvocation(\"my-tool\", [], { platform: \"win32\" }); // shim resolves to 900KB wrapper.bat\n\n// after\nconst inv = portableProcessInvocation(\"C:/proj/node_modules/.bin/my-tool.cmd\", [], { platform: \"win32\" }); // point at the genuine small npm shim","handlingStrategy":"validation","validationCode":"import { statSync } from \"node:fs\";\nfunction isSafeShim(executable) {\n  try {\n    const st = statSync(executable);\n    return st.isFile() && st.size <= 256 * 1024;\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const inv = portableProcessInvocation(cmd, args, { platform: \"win32\" });\n} catch (err) {\n  if (/cannot safely launch Windows command shim/.test(err.message)) {\n    // fall back to invoking the real executable path directly\n  } else throw err;\n}","preventionTips":["Point at the real .exe or Node script instead of .cmd shims when you control the path.","Reinstall packages whose shims look corrupted or oversized before running."],"tags":["windows","spawn","security","cmd-shim"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}