stablyai/orca · error
[plain-node-entry-guard] guarded ${missing.map((name) => `"$
Error message
[plain-node-entry-guard] guarded ${missing.map((name) => `"${name}"`).join(', ')} ${missing.length === 1 ? 'is not a rollup input' : 'are not rollup inputs'} anymore. Update PLAIN_NODE_ENTRY_NAMES/WORKER_THREAD_ENTRY_NAMES in plain-node-entry-guard.ts to the current entry names — a stale name silently stops guarding that entry. What it means
A Vite/Rollup build plugin guard (`assertEntryNamesAreRollupInputs`) fires at buildStart when any name in GUARDED_ENTRY_NAMES (the hardcoded lists PLAIN_NODE_ENTRY_NAMES and WORKER_THREAD_ENTRY_NAMES) is absent from the actual rollup input keys. The guard exists because writeBundle silently skips names that aren't in the bundle, so a renamed or removed entry would silently stop being checked — re-introducing the v1.4.129-rc.1 daemon outage class. The build aborts so you fix the list before the regression ships.
Source
Thrown at config/build-plugins/plain-node-entry-guard.ts:66
...WORKER_THREAD_ENTRY_NAMES
] as const
type EntryRuntime = 'plain-Node process' | 'worker thread'
// Subpaths (electron/main) are as unloadable as the bare module under plain Node.
const ELECTRON_REQUIRE_RE = /require\(\s*["'`]electron(?:\/[^"'`]+)?["'`]\s*\)/
// Why: writeBundle skips any name missing from the bundle, so a renamed or
// removed rollup input would silently drop that entry from the guard and let the
// regression back in. Pin the lists to the input keys at build start instead.
function assertEntryNamesAreRollupInputs(input: NormalizedInputOptions['input']): void {
if (typeof input === 'string' || Array.isArray(input)) {
return
}
const inputNames = new Set(Object.keys(input))
const missing = GUARDED_ENTRY_NAMES.filter((name) => !inputNames.has(name))
if (missing.length > 0) {
throw new Error(
`[plain-node-entry-guard] guarded ${missing.map((name) => `"${name}"`).join(', ')} ` +
`${missing.length === 1 ? 'is not a rollup input' : 'are not rollup inputs'} anymore. ` +
`Update PLAIN_NODE_ENTRY_NAMES/WORKER_THREAD_ENTRY_NAMES in plain-node-entry-guard.ts to ` +
`the current entry names — a stale name silently stops guarding that entry.`
)
}
}
function collectReachableChunks(
entry: OutputChunk,
byFileName: Map<string, OutputChunk>
): OutputChunk[] {
const seen = new Set<string>()
const reachable: OutputChunk[] = []
const stack = [entry.fileName]
while (stack.length > 0) {
const fileName = stack.pop() as string
if (seen.has(fileName)) {View on GitHub (pinned to 1136503c6a)
Solutions
- Read the error message: it names exactly which entries are missing (the `${missing}` list). For each missing name, either rename it in the guard list to match the new rollup input key, or remove it from PLAIN_NODE_ENTRY_NAMES/WORKER_THREAD_ENTRY_NAMES if the entry was intentionally deleted.
- Open electron.vite.config.ts:208 and compare the keys in the `input` object against GUARDED_ENTRY_NAMES in plain-node-entry-guard.ts:46 — every guarded name must appear as an input key.
- If you added a new plain-Node or worker-thread entry, add its name to the appropriate list so it stays guarded against electron require leaks.
Example fix
// before — rollup input in electron.vite.config.ts
daemon-entry: resolve('src/main/daemon/daemon-entry.ts')
// after (renamed to 'daemon')
daemon: resolve('src/main/daemon/daemon-entry.ts')
// plain-node-entry-guard.ts — must also update:
// before
const PLAIN_NODE_ENTRY_NAMES = ['daemon-entry', ...] as const
// after
const PLAIN_NODE_ENTRY_NAMES = ['daemon', ...] as const Defensive patterns
Strategy: validation
Validate before calling
// Run before the build to verify guard lists match rollup inputs
import { readFileSync } from 'fs'
const config = readFileSync('electron.vite.config.ts', 'utf8')
const guard = readFileSync('config/build-plugins/plain-node-entry-guard.ts', 'utf8')
const inputKeys = [...config.matchAll(/^(\S[\w/-]+):\s*resolve\(/gm)].map(m => m[1])
const guardNames = [...guard.matchAll(/'([\w/-]+)'/g)].map(m => m[1])
const stale = guardNames.filter(n => !inputKeys.includes(n))
if (stale.length) console.warn('Stale guard entries:', stale) Prevention
- When renaming a rollup input key, grep for the old name across config/ to find all references including the guard lists.
- Keep PLAIN_NODE_ENTRY_NAMES and WORKER_THREAD_ENTRY_NAMES directly beside the rollup input config or add a test that cross-checks them (the test at plain-node-entry-guard.test.ts:136 already covers this).
- Treat the guard lists as part of the build contract — any PR that changes rollup input keys must update them in the same commit.
When it happens
Trigger: Renaming a rollup input key in electron.vite.config.ts (e.g. changing 'daemon-entry' to 'daemon') without updating the corresponding entry in PLAIN_NODE_ENTRY_NAMES or WORKER_THREAD_ENTRY_NAMES in plain-node-entry-guard.ts. Also fires when removing an entry from the rollup input object without removing it from the guard lists.
Common situations: Refactoring the main process entry points in electron.vite.config.ts:208 (the rollupOptions.input object). Adding or removing a forked process entry, worker thread entry, or renaming an existing one. The guard list is maintained by hand against the rollup input keys, so any naming drift between the two triggers this.
Related errors
- [plain-node-entry-guard] "${entryName}" reaches chunk "${chu
- Invalid ORCA_ELECTRON_VITE_TARGET: ${target ?? '<unset>'}
- [plain-node-entry-guard] could not smoke-load daemon-entry.j
- [plain-node-entry-guard] daemon-entry.js did not exit within
- [plain-node-entry-guard] daemon-entry.js was killed by ${res
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/13b1c7c2bfe630d7.
Report an issue: GitHub.