stablyai/orca · critical
[plain-node-entry-guard] daemon-entry.js did not reject an e
Error message
[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} What it means
The smoke-loaded daemon-entry.js exited without error, without timeout, and without a signal, but either its exit status was 0 (success) or its stderr did not contain the DAEMON_USAGE_PREFIX string ('Usage: daemon-entry'). The smoke test expects the daemon to reject an empty argv by exiting non-zero with a usage message. Getting exit 0 or a missing usage prefix means the argv parser changed its rejection behavior — it either accepts empty argv (starts the daemon) or changed its error message format.
Source
Thrown at config/build-plugins/plain-node-entry-guard.ts:219
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 {
name: 'orca-plain-node-entry-guard',
buildStart(options: NormalizedInputOptions) {
assertEntryNamesAreRollupInputs(options.input)
},
writeBundle(options: NormalizedOutputOptions, bundle: OutputBundle) {View on GitHub (pinned to 1136503c6a)
Solutions
- Check src/main/daemon/daemon-entry.ts:85 — the error throw must produce a message starting with 'Usage: daemon-entry' on stderr with a non-zero exit code.
- If you intentionally changed the usage message, update DAEMON_USAGE_PREFIX in plain-node-entry-guard.ts:119 to match the new prefix.
- If exit status was 0, the daemon accepted empty argv — restore the rejection behavior so an accidental fork with no args fails fast instead of silently starting.
Example fix
// before — daemon-entry.ts changed error format
console.error('Error: missing --socket argument')
process.exit(1)
// after — keep the expected prefix
throw new Error('Usage: daemon-entry --socket <path> --token <path> [--log-file <path>]')
// process.exit(1) follows from the uncaught throw Defensive patterns
Strategy: validation
Validate before calling
// Verify daemon-entry's usage message matches DAEMON_USAGE_PREFIX
import { readFileSync } from 'fs'
function verifyUsagePrefix(daemonEntryPath, expectedPrefix) {
const source = readFileSync(daemonEntryPath, 'utf8')
// For source TS; for compiled JS the message is a string literal
if (!source.includes(expectedPrefix)) {
throw new Error(`daemon-entry must output '${expectedPrefix}' on empty argv — update DAEMON_USAGE_PREFIX if changed`)
}
} Prevention
- Keep DAEMON_USAGE_PREFIX in plain-node-entry-guard.ts:119 in sync with the actual usage message in daemon-entry.ts.
- Never change the error output destination from stderr to stdout — the smoke test only reads stderr.
- Always exit non-zero when rejecting argv — don't just log and continue.
When it happens
Trigger: The argv parser in src/main/daemon/daemon-entry.ts changed its error message to not start with 'Usage: daemon-entry' (DAEMON_USAGE_PREFIX is pinned at line 119 with a 'keep in sync' comment). The parser started returning instead of throwing on empty argv, causing a clean exit 0. The parser was refactored to use a different error reporting mechanism (e.g., yargs built-in help instead of a manual throw).
Common situations: Switching the argv parser library (e.g., from manual parsing to commander/yargs) which changes the usage message format. Making previously-required arguments optional. Changing the error output destination from stderr to stdout (the smoke only reads stderr).
Related errors
- [plain-node-entry-guard] daemon-entry.js did not exit within
- [plain-node-entry-guard] could not smoke-load daemon-entry.j
- [plain-node-entry-guard] daemon-entry.js was killed by ${res
- [plain-node-entry-guard] daemon-entry.js failed to load unde
- [plain-node-entry-guard] "${entryName}" reaches chunk "${chu
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/738df2e5203b9886.
Report an issue: GitHub.