{"record":{"id":"e513e34784cbe7e0","repo":"can1357/oh-my-pi","slug":"this-options-languagename-kernel-is-not-runnin","errorCode":null,"errorMessage":"${this.#options.languageName} kernel is not running","messagePattern":"(.+?) kernel is not running","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/eval/kernel-base.ts","lineNumber":214,"sourceCode":"\t\tthis.#exitedPromise = proc.exited;\n\t\tvoid this.#exitedPromise.then(code => {\n\t\t\tthis.#alive = false;\n\t\t\tthis.#abortPendingExecutions(`${this.#options.languageName} kernel exited with code ${code}`, {\n\t\t\t\tkernelKilled: true,\n\t\t\t});\n\t\t});\n\n\t\tthis.#startReader(proc.stdout as ReadableStream<Uint8Array>);\n\t\tthis.#startStderrDrain(proc.stderr as ReadableStream<Uint8Array>);\n\t}\n\n\tisAlive(): boolean {\n\t\treturn this.#alive && !this.#disposed;\n\t}\n\n\tasync execute(code: string, options?: TExecuteOptions): Promise<KernelExecuteResult> {\n\t\tif (!this.isAlive()) {\n\t\t\tthrow new Error(`${this.#options.languageName} kernel is not running`);\n\t\t}\n\n\t\tconst msgId = options?.id ?? Snowflake.next();\n\t\tconst { promise, resolve } = Promise.withResolvers<KernelExecuteResult>();\n\t\tconst pending: PendingExecution = {\n\t\t\tresolve,\n\t\t\toptions,\n\t\t\tstatus: \"ok\",\n\t\t\tcancelled: false,\n\t\t\ttimedOut: false,\n\t\t\tstdinRequested: false,\n\t\t\tsettled: false,\n\t\t\tkernelKilled: false,\n\t\t};\n\t\tthis.#pending.set(msgId, pending);\n\n\t\tconst finalize = () => {\n\t\t\tif (pending.settled) return;","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/eval/kernel-base.ts#L196-L232","documentation":"`KernelBase.execute` checks `isAlive()` (`#alive && !#disposed`) before queueing a code execution. If the kernel process has died, was never fully started, or was disposed, executing code is impossible and it throws `\"<language> kernel is not running\"`. This prevents sending messages to a dead kernel and hanging on a promise that would never resolve.","triggerScenarios":"Calling `execute(code)` on a kernel after `shutdown()`/`dispose()`, after the kernel process crashed or exited, or before `start()` completed successfully.","commonSituations":"Long-lived eval sessions whose Python/JS kernel process died (OOM, interpreter error); reusing a cached kernel object after the session was torn down; calling execute before awaiting `start()`.","solutions":["Check `kernel.isAlive()` before executing; restart via `start()` if dead","Recreate the kernel/session when it reports not alive — a dead process cannot be revived","Inspect kernel stderr/trace logs to find why the process exited (missing interpreter, import crash, OOM)"],"exampleFix":"// before\nconst result = await kernel.execute(code);\n// after\nif (!kernel.isAlive()) {\n  kernel = await createKernel(cwd); // restart\n}\nconst result = await kernel.execute(code);","handlingStrategy":"validation","validationCode":"if (!kernel.isAlive()) {\n  kernel = await createKernel({ cwd }); // restart before use\n}","typeGuard":"function isRunnableKernel(k: KernelBase<never, never> | null): k is KernelBase<never, never> {\n  return k !== null && k.isAlive();\n}","tryCatchPattern":"try {\n  return await kernel.execute(code);\n} catch (err) {\n  if (err instanceof Error && /kernel is not running/.test(err.message)) {\n    kernel = await createKernel({ cwd });\n    return await kernel.execute(code);\n  }\n  throw err;\n}","preventionTips":["Always await start() before execute","Check isAlive() before each execution in long-lived sessions","Monitor kernel process exit events and restart proactively","Capture kernel stderr to diagnose why it died"],"tags":["kernel","lifecycle","process","eval"],"backgroundTag":"kernel-not-running","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}