{"record":{"id":"c6e0c5417bd0a461","repo":"stablyai/orca","slug":"verify-packaged-daemon-entry-packaged-daemon-ent","errorCode":null,"errorMessage":"[verify-packaged-daemon-entry] packaged daemon-entry.js failed to load under plain Node:\n${stderr}","messagePattern":"\\[verify-packaged-daemon-entry\\] packaged daemon-entry\\.js failed to load under plain Node:\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"config/scripts/verify-packaged-daemon-entry.cjs","lineNumber":45,"sourceCode":"// users. Module-load proof only: with no args the entry must reach argv parsing\n// and print its \"Usage: daemon-entry\" error — a MODULE_NOT_FOUND or a missing\n// usage line means the packaged graph does not load and the build must fail.\n//\n// resourcesDir is the packaged Resources dir (Contents/Resources on macOS,\n// <appOutDir>/resources elsewhere). execPath defaults to the packaging Node.\nfunction verifyPackagedDaemonEntryBoots(resourcesDir, options = {}) {\n  const execPath = options.execPath || process.execPath\n  const entryPath = assertPackagedDaemonEntryExists(resourcesDir)\n\n  const result = spawnSync(execPath, [entryPath], { encoding: 'utf8', timeout: 10_000 })\n  if (result.error) {\n    throw new Error(\n      `[verify-packaged-daemon-entry] could not launch daemon-entry.js: ${result.error.message}`\n    )\n  }\n  const stderr = result.stderr || ''\n  if (/Cannot find module|MODULE_NOT_FOUND/.test(stderr)) {\n    throw new Error(\n      `[verify-packaged-daemon-entry] packaged daemon-entry.js failed to load under plain Node:\\n${stderr}`\n    )\n  }\n  if (!stderr.includes('Usage: daemon-entry')) {\n    throw new Error(\n      `[verify-packaged-daemon-entry] packaged daemon-entry.js did not reach argv parsing ` +\n        `(expected the \"Usage: daemon-entry\" error). stderr:\\n${stderr}`\n    )\n  }\n  console.log('[verify-packaged-daemon-entry] OK — packaged daemon-entry loads under plain Node')\n}\n\nmodule.exports = { assertPackagedDaemonEntryExists, verifyPackagedDaemonEntryBoots }\n","sourceCodeStart":27,"sourceCodeEnd":59,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/verify-packaged-daemon-entry.cjs#L27-L59","documentation":"Thrown by the packaged daemon entry verification script when daemon-entry.js was successfully launched under plain Node but its stderr output contains 'Cannot find module' or 'MODULE_NOT_FOUND'. This indicates a bundling regression: the packaged daemon entry's dependency graph is incomplete and references modules that weren't bundled or aren't resolvable. The comment at line 23 references v1.4.129-rc.1 which shipped exactly this class of bug (an Electron `require` leaked into the daemon bundle).","triggerScenarios":"The daemon-entry.js bundle was produced by esbuild/webpack but an externalized dependency was not marked as bundleable, leaving a runtime require that resolves under Electron's module system but not under plain Node. The verification deliberately runs under plain Node (not Electron) to catch this: Electron-specific requires like 'electron' itself or main-process-only modules fail to resolve.","commonSituations":"An esbuild external array was over-broad and excluded a dependency that should have been bundled; a new import was added to the daemon entry or its transitive dependencies that pulls in an Electron-only module; the bundler config marks 'electron' as external (correct for the main process bundle) but the daemon entry was incorrectly placed in the same build target; a Node version difference where a built-in module name changed.","solutions":["Read the stderr output in the error message — it names the exact module that could not be found.","If the module is 'electron' or an Electron-only package, ensure the daemon entry bundle does not import it; the daemon runs under plain Node, not Electron's runtime.","Check the esbuild/webpack config for the daemon entry build target and ensure all runtime dependencies are bundled (not externalized).","Run the daemon-entry bundle locally under plain Node to reproduce: node out/main/daemon-entry.js and observe the MODULE_NOT_FOUND error.","If the missing module is a legitimate Node built-in, verify the Node version used for verification matches the one the bundle targets."],"exampleFix":"// before — esbuild config marks too many packages as external\n//   external: ['electron', 'chokidar', 'node-pty']\n//\n// after — only electron is truly external for the daemon bundle\n//   external: ['electron']","handlingStrategy":"validation","validationCode":"// Before packaging, test the daemon entry bundle loads under plain Node.\nconst { spawnSync } = require('node:child_process')\n\nfunction preCheckDaemonBundleLoads(entryPath) {\n  const result = spawnSync(process.execPath, [entryPath], {\n    encoding: 'utf8',\n    timeout: 10_000\n  })\n  const stderr = result.stderr || ''\n  if (/Cannot find module|MODULE_NOT_FOUND/.test(stderr)) {\n    const match = stderr.match(/Cannot find module '([^']+)'/)\n    return {\n      ok: false,\n      missingModule: match ? match[1] : 'unknown',\n      stderr\n    }\n  }\n  return { ok: true }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run the daemon entry bundle under plain Node (not Electron) as a separate CI step before packaging to catch module resolution issues early.","Review the esbuild/webpack external array for the daemon entry build target — only 'electron' should be external, not Node built-ins or bundled dependencies.","When adding a new import to the daemon entry or its transitive dependencies, verify it doesn't pull in Electron-only modules by checking the bundle output."],"tags":["electron-packaging","daemon","bundling","esbuild","module-resolution","ci-gate"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}