can1357/oh-my-pi · error · Error
JS eval worker smoke fell back from the isolated subprocess
Error message
JS eval worker smoke fell back from the isolated subprocess
What it means
This error comes from the JS eval worker smoke probe (`smokeTestJsEvalWorker`), which spawns the JS evaluator in a real isolated subprocess and verifies it completes the `init` handshake. After init succeeds, it asserts `worker.mode === "process"`; if the worker silently degraded to an inline fallback (same-realm execution instead of a separate process), the probe throws. This guards the distribution-build failure mode where process loading breaks and every eval cell strands on the init timeout.
Source
Thrown at packages/coding-agent/src/eval/js/context-manager.ts:263
* the failure mode that motivated `installWorkerInbox`. Wired into
* `omp --smoke-test` so binary / source / tarball installs all exercise it.
*/
export async function smokeTestJsEvalWorker(): Promise<void> {
const worker = spawnJsWorker();
const session: JsSession = {
sessionKey: "smoke",
sessionId: "smoke",
cwd: process.cwd(),
worker,
state: "alive",
pending: new Map(),
ownerIds: new Set(),
hasFallbackOwner: false,
};
try {
await initWorker(session, { cwd: process.cwd(), sessionId: "smoke" }, WORKER_INIT_TIMEOUT_MS);
if (worker.mode !== "process") {
throw new Error("JS eval worker smoke fell back from the isolated subprocess");
}
} finally {
await worker.terminate().catch(() => undefined);
}
}
async function runOnce(
session: JsSession,
options: {
sessionId: string;
cwd: string;
session: ToolSession;
localRoots?: Record<string, string>;
code: string;
filename: string;
runState: VmRunState;
},
): Promise<{ value: unknown }> {View on GitHub (pinned to 9690622007)
Solutions
- Check whether spawnJsWorker can return a non-process mode in this environment and fix the spawn path so `workerHostEntry()` resolves (Bun.main) and the worker re-enters the CLI entrypoint.
- Verify `declareWorkerHostEntry()` is called at CLI startup and the `__omp_worker_js_eval` selector is dispatched in cli.ts before the command registry loads.
- Run the worker from the official omp CLI entrypoint (source cli.ts, dist/cli.js, or the compiled binary) rather than a custom embedder that defeats worker-host detection.
- If running under `bun test`/SDK embedding where workerHostEntry() is legitimately null, expect the inline fallback and do not assert process mode there.
Example fix
// before (embedding SDK, worker loads inline)
await smokeTestJsEvalWorker(); // throws: fell back from isolated subprocess
// after
import { declareWorkerHostEntry } from "@oh-my-pi/pi-utils/env";
declareWorkerHostEntry(); // at entrypoint startup, before spawning workers
await smokeTestJsEvalWorker(); Defensive patterns
Strategy: validation
Validate before calling
const worker = spawnJsWorker();
if (worker.mode !== "process") {
throw new Error("worker did not spawn as isolated subprocess");
} Type guard
function isProcessWorker(w: { mode: string }): w is { mode: "process" } & typeof w {
return w.mode === "process";
} Try / catch
try {
await initWorker(session, opts, WORKER_INIT_TIMEOUT_MS);
} catch (err) {
if (String(err?.message).includes("fell back from the isolated subprocess")) {
// report install/wiring failure; fall back to skipping eval features
}
throw err;
} Prevention
- Always start the CLI through its official entrypoint (cli.ts, dist/cli.js, or compiled binary) so workerHostEntry() resolves.
- Keep declareWorkerHostEntry() and the worker selector dispatch table in sync when adding workers.
- Run `omp --smoke-test` after packaging changes to catch process-load regressions early.
When it happens
Trigger: Running `omp --smoke-test` (or any caller of smokeTestJsEvalWorker) when spawnJsWorker() returns a worker whose `mode` is not "process" — e.g. `workerHostEntry()` returned null and the fallback loaded the worker module inline, or the process-load path regressed and init ran in-realm.
Common situations: A packaged/binary install where the worker-host entry is missing or argv selectors were not dispatched; embedding the CLI in a host that bypasses `declareWorkerHostEntry()`; a refactor of spawnJsWorker that changed mode negotiation; running the smoke probe in an environment where subprocess spawning is unavailable.
Related errors
- omp task exceeded hard timeout
- blob broker worker requires ${BLOB_BROKER_SOCKET_ENV} and ${
- ${argv[0]} exited with code ${exitCode}: ${stderr.trim().sli
- ${argv[0]} printed no URL on stdout
- ${(result.stderr || result.stdout).replace(/\s+/g, " ").trim
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5cdffe72c8bcece8.
Report an issue: GitHub.