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

  1. 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.
  2. 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.
  3. 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 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


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