{"record":{"id":"91b8c4df3d535f5d","repo":"JuliusBrussee/caveman","slug":"windows-command-shim-target-is-missing-script-91b8c4","errorCode":null,"errorMessage":"Windows command shim target is missing: ${script}","messagePattern":"Windows command shim target is missing: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/mcp-servers/caveman-shrink/spawn-options.js","lineNumber":54,"sourceCode":"    }\n  }\n  return null;\n}\n\nfunction getSpawnInvocation(command, args, platform = process.platform, env = process.env) {\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 source = fs.readFileSync(executable, 'utf8');\n  let relativeScript = null;\n  for (const line of source.split(/\\r?\\n/)) {\n    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) { relativeScript = match[1]; break; }\n  }\n  if (!relativeScript) throw new Error(`cannot safely launch non-Node Windows command shim: ${executable}`);\n  const script = path.resolve(path.dirname(executable), ...relativeScript.split(/[\\\\/]+/));\n  if (!fs.statSync(script).isFile()) throw new Error(`Windows command shim target is missing: ${script}`);\n  return { command: process.execPath, args: [script, ...args] };\n}\n\nfunction getSpawnOptions(platform = process.platform) {\n  return {\n    stdio: ['pipe', 'pipe', 'inherit'],\n    windowsHide: true,\n  };\n}\n\nmodule.exports = { getSpawnInvocation, getSpawnOptions, resolveWindowsCommand };\n","sourceCodeStart":36,"sourceCodeEnd":66,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/src/mcp-servers/caveman-shrink/spawn-options.js#L36-L66","documentation":"getSpawnInvocation() parsed a Node-launching .cmd/.bat shim successfully but the .js/.cjs/.mjs target it forwards to (resolved next to the shim) does not exist as a file. The launcher refuses to guess and throws before spawning.","triggerScenarios":"A partial npm install where the shim landed but the package JS did not; the package was updated or moved and the shim is stale; node_modules pruned by a dependency cleaner while .bin shims remained.","commonSituations":"Interrupted npm or pnpm installs; npm prune/autoclean leaving orphaned .bin entries; copying node_modules between machines or paths where the relative %~dp0 target breaks; package hoisting quirks in monorepos.","solutions":["Delete node_modules and do a clean, lockfile-faithful install (npm ci) of the package providing the shim","Verify the printed target path in the error actually exists; if it is wrong the shim is stale — reinstall","Bypass the shim: invoke node directly on the package's real entrypoint"],"exampleFix":"# before (broken partial install)\n# Windows command shim target is missing: ...\\node_modules\\.bin\\..\\foo\\cli.js\n\n# after\nnpm ci   # or: rm -rf node_modules && npm install","handlingStrategy":"fallback","validationCode":"const fs = require(\"node:fs\");\nconst path = require(\"node:path\");\n// before spawning via a .cmd shim on Windows, confirm its JS target exists\nfunction shimTargetExists(shimPath) {\n  const m = fs.readFileSync(shimPath, \"utf8\").match(/\"%(?:dp0%|~dp0)\\\\([^\"\\r\\n]+\\.(?:cjs|mjs|js))\"\\s+%\\*/i);\n  return m ? fs.statSync(path.resolve(path.dirname(shimPath), m[1])).isFile() : false;\n}","typeGuard":null,"tryCatchPattern":"try {\n  spawn(invocation.command, invocation.args);\n} catch (e) {\n  if (/shim target is missing/.test(String(e?.message))) {\n    await reinstallPackage();\n    spawn(process.execPath, [knownEntry, ...args]);\n  } else throw e;\n}","preventionTips":["Use npm ci (not ad-hoc installs) so node_modules matches the lockfile exactly","Avoid moving or partially copying node_modules between machines"],"tags":["windows","spawn","npm","filesystem"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}