{"record":{"id":"6d1651a18a81de20","repo":"stablyai/orca","slug":"unknown-ephemeral-vm-runtime-args-runtimeid","errorCode":null,"errorMessage":"Unknown ephemeral VM runtime: ${args.runtimeId}","messagePattern":"Unknown ephemeral VM runtime: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/ephemeral-vm-runtime-service.ts","lineNumber":147,"sourceCode":"    connectionMode: connection.type,\n    cleanupStatus: args.recipe.destroyDisabled ? 'disabled' : 'not_started',\n    ...(args.recipe.destroyDisabled ? { cleanupDisabled: true } : {}),\n    createdAt: now,\n    updatedAt: now,\n    recipeResult: start.result\n  })\n\n  return { ok: true, start, runtime }\n}\n\nexport async function cleanupEphemeralVmRuntime(\n  args: CleanupEphemeralVmRuntimeArgs\n): Promise<CleanupEphemeralVmRuntimeResult> {\n  const existing = listEphemeralVmRuntimes(args.userDataPath).find(\n    (entry) => entry.id === args.runtimeId\n  )\n  if (!existing) {\n    throw new Error(`Unknown ephemeral VM runtime: ${args.runtimeId}`)\n  }\n\n  const now = args.now ?? Date.now()\n  const running = updateEphemeralVmRuntimeStatus(args.userDataPath, existing.id, {\n    status: 'cleanup_pending',\n    cleanupStatus: args.recipe.destroyDisabled ? 'disabled' : 'running',\n    cleanupLastAttemptAt: now,\n    cleanupLastError: null,\n    updatedAt: now\n  })\n  const cleanup = await runEphemeralVmRecipeCleanup({\n    repoPath: args.repoPath,\n    recipe: args.recipe,\n    context: contextFromRuntime(args.repoPath, running),\n    recipeResult: running.recipeResult,\n    signal: args.signal,\n    onStdout: args.onStdout,\n    onStderr: args.onStderr","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ephemeral-vm-runtime-service.ts#L129-L165","documentation":"cleanupEphemeralVmRuntime looks up the runtime by id in listEphemeralVmRuntimes(userDataPath); a miss means the id was never created, was already cleaned, or points at a different userDataPath. The error throws before any destroy recipe logic runs.","triggerScenarios":"Calling cleanupEphemeralVmRuntime({ runtimeId, userDataPath, ... }) where no record's id matches args.runtimeId (ephemeral-vm-runtime-service.ts:143-147).","commonSituations":"Double-cleanup (runtime already destroyed); wrong userDataPath (different user/install); an id copied from a different workspace; the runtime record file was deleted out of band.","solutions":["Check the runtime still exists via listEphemeralVmRuntimes(userDataPath) before calling cleanup.","Pass the same userDataPath that was used to start the runtime.","Treat 'unknown runtime' as already-cleaned and make cleanup idempotent in the caller."],"exampleFix":"// before\nawait cleanupEphemeralVmRuntime({ runtimeId, userDataPath, recipe, repoPath })\n\n// after\nconst exists = listEphemeralVmRuntimes(userDataPath).some((r) => r.id === runtimeId)\nif (exists) await cleanupEphemeralVmRuntime({ runtimeId, userDataPath, recipe, repoPath })","handlingStrategy":"validation","validationCode":"const exists = listEphemeralVmRuntimes(userDataPath).some((r) => r.id === runtimeId)\nif (!exists) { /* already cleaned or wrong path; skip */ }","typeGuard":"function isUnknownRuntimeError(e: unknown): boolean {\n  return e instanceof Error && /^Unknown ephemeral VM runtime:/.test(e.message)\n}","tryCatchPattern":"try { await cleanupEphemeralVmRuntime(args) }\ncatch (e) { if (isUnknownRuntimeError(e)) { /* idempotent: already gone */ } else throw e }","preventionTips":["Make cleanup idempotent in the caller.","Reuse the same userDataPath across start/cleanup.","Look up the runtime id before calling lifecycle verbs."],"tags":["ephemeral-vm","runtime","lifecycle","validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}