{"record":{"id":"259d30d291b6185f","repo":"slopus/happy","slug":"entrypoint-entrypoint-does-not-exist","errorCode":null,"errorMessage":"Entrypoint ${entrypoint} does not exist","messagePattern":"Entrypoint (.+?) does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/happy-cli/src/utils/spawnHappyCLI.ts","lineNumber":101,"sourceCode":"  // However, we log it as 'happy' here because other engineers are typically looking\n  // for when \"happy\" was started and don't care about the underlying node process\n  // details and flags we use to achieve the same result.\n  const fullCommand = `happy ${args.join(' ')}`;\n  logger.debug(`[SPAWN HAPPY CLI] Spawning: ${fullCommand} in ${directory}`);\n  \n  // Use the same Node.js flags that the wrapper script uses\n  const nodeArgs = [\n    '--no-warnings',\n    '--no-deprecation',\n    entrypoint,\n    ...args\n  ];\n\n  // Sanity check of the entrypoint path exists\n  if (!existsSync(entrypoint)) {\n    const errorMessage = `Entrypoint ${entrypoint} does not exist`;\n    logger.debug(`[SPAWN HAPPY CLI] ${errorMessage}`);\n    throw new Error(errorMessage);\n  }\n  \n  const runtime = isBun() ? 'bun' : 'node';\n  // Use cross-spawn so `node` resolves to `node.exe` on Windows.\n  // Since Node's CVE-2024-27980 hardening, child_process.spawn('node', ...)\n  // on Windows no longer falls back to appending `.exe`, producing ENOENT\n  // even when node is on PATH (issue #1082).\n  return crossSpawn(runtime, nodeArgs, {\n    windowsHide: true,\n    ...options,\n  });\n}\n","sourceCodeStart":83,"sourceCodeEnd":114,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/utils/spawnHappyCLI.ts#L83-L114","documentation":"spawnHappyCLI launches the happy CLI as a child process (via bun or node). Before spawning, it sanity-checks that the resolved entrypoint file exists on disk with existsSync; if not, it throws this Error immediately instead of letting the runtime fail with an opaque ENOENT. This guards against broken installs, stale version paths, or invalid HOME-based path resolution.","triggerScenarios":"Calling spawnHappyCLI (directly or via terminalHappyProcess, daemonProcess, happyProcess, restartOnStaleVersionAndHeartbeat, or child) when the resolved entrypoint path — typically a compiled CLI script under a versioned directory — does not exist on disk at spawn time.","commonSituations":"Partial or corrupted npm/global install where the CLI bundle was removed; a stale daemon referencing an old version directory that was cleaned by an update; HOME or cache-directory misconfiguration pointing at a nonexistent path; running from a source checkout without building the entrypoint; filesystem race during an upgrade while the daemon restarts.","solutions":["Reinstall/update the happy CLI so the entrypoint file exists (npm install -g happy-coder or the package's recommended update command).","Log/inspect the entrypoint path in the error message and verify it exists: ls <path>.","Kill stale daemons/processes that pinned an old version path, then restart (restartOnStaleVersionAndHeartbeat usually recovers this automatically).","If running from source, build the CLI so the entrypoint artifact is generated.","Check HOME/cache env vars (e.g. HOME, XDG dirs) resolve to a real writable directory."],"exampleFix":"// before\nspawnHappyCLI(['doctor']); // throws: Entrypoint /home/me/.npm/.../cli.js does not exist\n// after\n// reinstall so the bundle exists, or guard:\nif (!existsSync(entrypoint)) { await updateHappyCLI(); }\nawait spawnHappyCLI(['doctor']);","handlingStrategy":"validation","validationCode":"import { existsSync } from 'fs';\n// resolve entrypoint the same way the library does, then:\nif (!existsSync(entrypoint)) {\n  throw new Error(`happy CLI entrypoint missing at ${entrypoint}; reinstall happy-coder`);\n}","typeGuard":"function isEntrypointPresent(path: string): boolean {\n  return typeof path === 'string' && path.length > 0 && existsSync(path);\n}","tryCatchPattern":"try {\n  await spawnHappyCLI(args);\n} catch (err) {\n  if ((err as Error).message.startsWith('Entrypoint')) {\n    await reinstallOrUpdateHappyCLI();\n    await spawnHappyCLI(args); // retry once after reinstall\n  } else throw err;\n}","preventionTips":["Keep the CLI installed and updated in the same package manager used to run it.","Restart daemons after upgrades so they don't pin deleted version paths.","Verify the install after updates: run `happy --version` before spawning programmatically.","Avoid manipulating or cleaning the CLI's cache/install directory while processes run."],"tags":["spawn","filesystem","cli","process"],"backgroundTag":"entrypoint-not-found","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}