{"record":{"id":"f3dafaefc86e72b5","repo":"can1357/oh-my-pi","slug":"vibemon-vm-sandbox-id-entered-state-before-b","errorCode":null,"errorMessage":"Vibemon VM ${sandbox.id} entered ${state} before becoming ready","messagePattern":"Vibemon VM (.+?) entered (.+?) before becoming ready","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/metaharness/src/tb/vmon.ts","lineNumber":66,"sourceCode":"\nfunction clientFor(config: VmonConfig): Client {\n\tconst key = `${config.url}\\0${config.token}`;\n\tlet client = clients.get(key);\n\tif (!client) {\n\t\tclient = connect(config.url, { token: config.token || undefined });\n\t\tclients.set(key, client);\n\t}\n\treturn client;\n}\n\nasync function waitUntilRunning(sandbox: Sandbox, timeoutSec: number): Promise<void> {\n\tconst deadline = Date.now() + timeoutSec * 1_000;\n\twhile (Date.now() < deadline) {\n\t\tconst info = await sandbox.refresh();\n\t\tconst state = String(info.observed_state ?? info.status ?? \"\").toLowerCase();\n\t\tif (state === \"running\") return;\n\t\tif ([\"exited\", \"failed\", \"stopped\", \"terminated\"].includes(state)) {\n\t\t\tthrow new Error(`Vibemon VM ${sandbox.id} entered ${state} before becoming ready`);\n\t\t}\n\t\tawait Bun.sleep(250);\n\t}\n\tthrow new Error(`Timed out waiting ${timeoutSec} seconds for Vibemon VM ${sandbox.id} to become ready`);\n}\n\nasync function archiveDirectory(root: string): Promise<Blob> {\n\tconst entries: Record<string, Uint8Array> = {};\n\tconst visit = async (dir: string): Promise<void> => {\n\t\tfor (const entry of await fs.readdir(dir, { withFileTypes: true })) {\n\t\t\tconst absolute = path.join(dir, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait visit(absolute);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\tconst relative = path.relative(root, absolute).split(path.sep).join(\"/\");\n\t\t\t\tentries[relative] = new Uint8Array(await Bun.file(absolute).arrayBuffer());\n\t\t\t}\n\t\t}","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/metaharness/src/tb/vmon.ts#L48-L84","documentation":"waitUntilRunning polls the Vibemon sandbox's observed state until it reports running. If the sandbox instead reports a terminal state (exited, failed, stopped, or terminated) before ever becoming ready, this error is thrown immediately with the VM id and the observed state, rather than waiting out the whole timeout.","triggerScenarios":"Calling start() on a Vibemon VM whose container/VM exits, fails, stops, or is terminated during the readiness poll window — e.g. image crash on boot, bad entrypoint, OOM kill, or externally issued stop.","commonSituations":"Broken VM image that crashes at startup; insufficient host resources causing OOM; orchestrator preempting the sandbox; concurrent run killing the sandbox by name.","solutions":["Inspect VM/container logs for the sandbox id reported in the message to find the boot failure","Validate the VM image boots standalone (run it locally with the same entrypoint)","Increase host memory/CPU or reduce concurrent sandboxes to avoid OOM/preemption","Check for other processes or cleanup jobs stopping the sandbox during startup"],"exampleFix":"// before: crashed image\nnew Vibemon({ image: \"my-vm:broken\" })\n// after: validated image that reaches running state\nnew Vibemon({ image: \"my-vm:fixed\", resources: { memoryMB: 4096 } })","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await vm.start();\n} catch (err) {\n  if (/entered (exited|failed|stopped|terminated) before becoming ready/.test(err.message)) {\n    const logs = await fetchSandboxLogs(vm.id);\n    logger.error(\"VM boot failed\", { id: vm.id, logs });\n    throw err; // boot failure is usually not transient; surface with logs\n  }\n  throw err;\n}","preventionTips":["Validate VM images boot standalone before registering them for trials","Right-size host memory/CPU to avoid OOM kills during parallel starts","Avoid concurrent lifecycle operations (stop/terminate) on the same sandbox id"],"tags":["vm","startup","polling"],"backgroundTag":"vm-exited-before-ready","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}