{"record":{"id":"4f428d2717ab5ba1","repo":"can1357/oh-my-pi","slug":"vibe-sessions-require-async-execution-no-backgrou","errorCode":null,"errorMessage":"Vibe sessions require async execution (no background job manager is available).","messagePattern":"Vibe sessions require async execution \\(no background job manager is available\\)\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/vibe/runtime.ts","lineNumber":533,"sourceCode":"\t\t\tthrow new ToolError(\"Vibe mode exit requires atomic parent-session persistence.\");\n\t\t}\n\t\tawait appendEntriesAtomically.call(sessionManager, () => {\n\t\t\tfor (const record of persistedPending) {\n\t\t\t\tsessionManager.appendCustomEntry(VIBE_LIFECYCLE_CUSTOM_TYPE, {\n\t\t\t\t\t...this.#eventBase(record),\n\t\t\t\t\taction: \"tombstone\",\n\t\t\t\t\treason: \"mode-exit\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tsessionManager.appendModeChange?.(\"none\");\n\t\t});\n\t\tfor (const record of pending) record.terminalPersisted = true;\n\t}\n\n\t#manager(session: ToolSession): AsyncJobManager {\n\t\tconst manager = session.asyncJobManager;\n\t\tif (!manager) {\n\t\t\tthrow new ToolError(\"Vibe sessions require async execution (no background job manager is available).\");\n\t\t}\n\t\treturn manager;\n\t}\n\n\t#record(scope: VibeOwnerScope, id: string): VibeRecord {\n\t\tconst record = this.#records.get(scopeKey(scope, id.trim()));\n\t\tif (!record || !matchesScope(record, scope)) {\n\t\t\tconst roster = this.#listIds(scope);\n\t\t\tthrow new ToolError(\n\t\t\t\t`Unknown vibe session \"${id}\".${roster.length > 0 ? ` Active sessions: ${roster.join(\", \")}` : \" No sessions — spawn one with vibe_spawn.\"}`,\n\t\t\t);\n\t\t}\n\t\treturn record;\n\t}\n\n\t#registeredAgent(record: VibeRecord): AgentRef | undefined {\n\t\tconst ref = AgentRegistry.global().get(record.id);\n\t\tif (ref?.kind !== \"sub\" || ref.parentId !== record.ownerId) return undefined;","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/vibe/runtime.ts#L515-L551","documentation":"Vibe workers run as background turn jobs, so the registry requires session.asyncJobManager. #manager() throws when the session has no async job manager — vibe cannot schedule, queue, or track worker turns. Any spawn or turn operation on such a session fails before any worker is created.","triggerScenarios":"Calling vibe spawn or a worker-turn operation (→ #spawnLocked/#manager) on a ToolSession whose asyncJobManager is undefined — e.g. sessions created without background-job support, restricted/embedded runtimes, or sessions configured for synchronous-only execution.","commonSituations":"SDK embeddings that omit the async job manager wiring; headless/one-shot runs where background jobs are disabled; tests constructing minimal ToolSession doubles.","solutions":["Wire an AsyncJobManager into the session (session.asyncJobManager) before using vibe mode.","Run vibe mode in the standard CLI/TUI runtime where the async job manager is always installed.","If embedding, initialize background-job support on the session during setup."],"exampleFix":"// before\nconst session = createSession({ asyncJobManager: undefined });\nawait vibe.spawn(session, { cli: \"fast\", prompt }); // throws\n// after\nconst session = createSession({ asyncJobManager: new AsyncJobManager() });\nawait vibe.spawn(session, { cli: \"fast\", prompt });","handlingStrategy":"validation","validationCode":"if (!session.asyncJobManager) {\n  throw new Error(\"Vibe requires a session with async job support; enable background jobs\");\n}","typeGuard":"function supportsAsyncJobs(s: ToolSession): boolean {\n  return !!s.asyncJobManager;\n}","tryCatchPattern":"try {\n  await vibe.spawn(session, { cli, prompt });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"async execution\")) {\n    throw new Error(\"Enable background job support on this session to use vibe mode\");\n  } else throw err;\n}","preventionTips":["Use the standard CLI/TUI session factory, which installs the async job manager","In embeddings, initialize AsyncJobManager during session setup","Gate vibe features behind an asyncJobManager capability check in your UI"],"tags":["session","configuration","async"],"backgroundTag":"missing-async-job-manager","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}