{"record":{"id":"bb221d7768f255b6","repo":"JuliusBrussee/caveman","slug":"windows-command-shim-target-is-missing-script","errorCode":null,"errorMessage":"Windows command shim target is missing: ${script}","messagePattern":"Windows command shim target is missing: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/portable-process.ts","lineNumber":63,"sourceCode":"    env?: NodeJS.ProcessEnv;\n    execPath?: string;\n  } = {},\n): PortableInvocation {\n  const platform = options.platform ?? process.platform;\n  const env = options.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 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: options.execPath ?? process.execPath, args: [script, ...args] };\n}\n\nexport function hostShellInvocation(\n  source: string,\n  platform: NodeJS.Platform = process.platform,\n  env: NodeJS.ProcessEnv = process.env,\n): PortableInvocation {\n  if (platform === \"win32\") {\n    return {\n      command: envValue(env, \"ComSpec\") ?? \"cmd.exe\",\n      args: [\"/d\", \"/s\", \"/c\", source],\n    };\n  }\n  return { command: \"/bin/sh\", args: [\"-c\", source] };\n}\n\nexport function killProcessTree(","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/portable-process.ts#L45-L81","documentation":"The final step of Windows shim handling resolves the Node script referenced inside a verified .cmd shim and statSyncs it. If that target .js file does not exist as a regular file, the library throws 'Windows command shim target is missing' rather than launching node with a nonexistent script. This typically means the shim is stale relative to the package contents.","triggerScenarios":"The .cmd wrapper points at ..\\some-script.js that was deleted, renamed, or never installed — e.g. after a partial install, a package downgrade that changed file layout, or a git-clean that removed untracked files under node_modules.","commonSituations":"Partial or interrupted npm install, node_modules pruned by a disk-cleanup tool, monorepo hoisting moved the real script while a stale .bin shim remained, or copying node_modules between machines with missing files.","solutions":["Reinstall dependencies so shims and targets are regenerated consistently: rm -rf node_modules && npm install","Verify the target manually: open the .cmd, find the script path, confirm the file exists","In monorepos, run the package's bin via the workspace path instead of a hoisted .bin shim","Check for case-sensitivity mismatches after copying a project from macOS/Windows to Linux or vice versa"],"exampleFix":"# before\n# .bin/build-tool.cmd points to ..\\..\\lib\\cli.js which does not exist\n\n# after\nrm -rf node_modules package-lock.json.orig && npm install\n# shim and target are regenerated in sync","handlingStrategy":"retry","validationCode":"import { statSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nfunction shimTargetExists(executable: string): boolean {\n  const body = readFileSync(executable, \"utf8\");\n  const m = body.match(/[\"']([^\"']*\\.js)[\"']/);\n  if (!m) return false;\n  try { return statSync(resolve(dirname(executable), m[1])).isFile(); } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const inv = portableInvocation(cmd, args);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"shim target is missing\")) {\n    // retry once after reinstalling deps or fall back to the direct script path\n  }\n  throw e;\n}","preventionTips":["Clean install (rm -rf node_modules && npm install) when bin layout looks stale","In monorepos, prefer workspace-relative script paths over hoisted .bin shims","CI should fail fast on missing bin targets rather than retrying flakily"],"tags":["windows","process-spawn","npm","installation","stale-shim"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}