stablyai/orca · critical

[plain-node-entry-guard] daemon-entry.js failed to load unde

Error message

[plain-node-entry-guard] daemon-entry.js failed to load under plain Node:\n${stderr}

What it means

After the smoke-loaded daemon-entry.js process exits, its stderr is scanned for `/Cannot find module|MODULE_NOT_FOUND/`. If matched, this error fires with the full stderr. This catches gross load failures — an unresolved `require()` in the daemon's module graph under plain Node. The comment clarifies this is NOT the electron regression guard (that's the static scan in error [1]); this only catches missing runtime dependencies that fail to resolve at load time.

Source

Thrown at config/build-plugins/plain-node-entry-guard.ts:214

        `${result.error.message}`
    )
  }
  // Almost always means the daemon stopped rejecting an empty argv and started
  // listening instead.
  if (result.timedOut) {
    throw new Error(
      `[plain-node-entry-guard] daemon-entry.js did not exit within ${timings.timeoutMs}ms on an ` +
        `empty argv under plain Node, so the smoke killed it.`
    )
  }
  if (result.signal) {
    throw new Error(
      `[plain-node-entry-guard] daemon-entry.js was killed by ${result.signal} under plain Node.`
    )
  }
  const stderr = result.stderr
  if (/Cannot find module|MODULE_NOT_FOUND/.test(stderr)) {
    throw new Error(
      `[plain-node-entry-guard] daemon-entry.js failed to load under plain Node:\n${stderr}`
    )
  }
  if (result.status === 0 || !stderr.includes(DAEMON_USAGE_PREFIX)) {
    throw new Error(
      `[plain-node-entry-guard] daemon-entry.js did not reject an empty argv under plain Node ` +
        `(expected a non-zero exit and the "${DAEMON_USAGE_PREFIX}" error, got exit ` +
        `${result.status}). stderr:\n${stderr}`
    )
  }
}

export function createPlainNodeEntryGuardPlugin(
  smokeTimings: SmokeTimings = DEFAULT_SMOKE_TIMINGS
): Plugin {
  let daemonOutputDir: string | undefined

  return {

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Read the stderr in the error message — it names the exact module that couldn't be found.
  2. If it's a bare package specifier (e.g., 'node-pty'), ensure it's listed in PACKAGED_RUNTIME_PACKAGE_ROOTS in packaged-runtime-node-modules.cjs so it gets copied to resources/node_modules.
  3. If it's a relative path or subpath, check that the asarUnpack config in electron-builder.config.cjs includes the directory containing that file.
  4. Run the smoke test manually: `node out/main/daemon-entry.js` from the build output directory to reproduce and debug interactively.

Example fix

// before — daemon-entry imports a new dep not in packaged runtime roots
const { foo } = require('new-package')

// after — add to PACKAGED_RUNTIME_PACKAGE_ROOTS in packaged-runtime-node-modules.cjs
const PACKAGED_RUNTIME_PACKAGE_ROOTS = [
  // ...existing entries...
  'new-package'
]
Defensive patterns

Strategy: validation

Validate before calling

// Verify all externalized deps resolve under plain Node before packaging
import { spawnSync } from 'child_process'
import { join } from 'path'
function verifyDaemonGraphResolves(outputDir) {
  const result = spawnSync(process.execPath, [join(outputDir, 'daemon-entry.js')], {
    timeout: 5000, stdio: 'pipe'
  })
  if (/Cannot find module|MODULE_NOT_FOUND/.test(result.stderr.toString())) {
    throw new Error(`Unresolved require in daemon graph:\n${result.stderr}`)
  }
}

Prevention

When it happens

Trigger: A runtime dependency that the daemon graph require()s is not available under plain Node — e.g., a package that was externalized by Rollup but whose node_modules copy is missing from the output directory, or a native addon (.node file) that can't be loaded. The MODULE_NOT_FOUND can also come from a subpath import that resolves under Electron's module system but not under plain Node.

Common situations: Adding a new dependency to daemon-entry's import graph without adding it to the packaged node_modules. A dependency that worked in dev (where node_modules is present) but fails in the build output directory where only specific packages are copied. Native module path resolution differences between Electron and plain Node.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/6bc213c11ef84143. Report an issue: GitHub.