can1357/oh-my-pi · error · ToolError
Vibe sessions require async execution (no background job man
Error message
Vibe sessions require async execution (no background job manager is available).
What it means
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.
Source
Thrown at packages/coding-agent/src/vibe/runtime.ts:533
throw new ToolError("Vibe mode exit requires atomic parent-session persistence.");
}
await appendEntriesAtomically.call(sessionManager, () => {
for (const record of persistedPending) {
sessionManager.appendCustomEntry(VIBE_LIFECYCLE_CUSTOM_TYPE, {
...this.#eventBase(record),
action: "tombstone",
reason: "mode-exit",
});
}
sessionManager.appendModeChange?.("none");
});
for (const record of pending) record.terminalPersisted = true;
}
#manager(session: ToolSession): AsyncJobManager {
const manager = session.asyncJobManager;
if (!manager) {
throw new ToolError("Vibe sessions require async execution (no background job manager is available).");
}
return manager;
}
#record(scope: VibeOwnerScope, id: string): VibeRecord {
const record = this.#records.get(scopeKey(scope, id.trim()));
if (!record || !matchesScope(record, scope)) {
const roster = this.#listIds(scope);
throw new ToolError(
`Unknown vibe session "${id}".${roster.length > 0 ? ` Active sessions: ${roster.join(", ")}` : " No sessions — spawn one with vibe_spawn."}`,
);
}
return record;
}
#registeredAgent(record: VibeRecord): AgentRef | undefined {
const ref = AgentRegistry.global().get(record.id);
if (ref?.kind !== "sub" || ref.parentId !== record.ownerId) return undefined;View on GitHub (pinned to 9690622007)
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.
Example fix
// before
const session = createSession({ asyncJobManager: undefined });
await vibe.spawn(session, { cli: "fast", prompt }); // throws
// after
const session = createSession({ asyncJobManager: new AsyncJobManager() });
await vibe.spawn(session, { cli: "fast", prompt }); Defensive patterns
Strategy: validation
Validate before calling
if (!session.asyncJobManager) {
throw new Error("Vibe requires a session with async job support; enable background jobs");
} Type guard
function supportsAsyncJobs(s: ToolSession): boolean {
return !!s.asyncJobManager;
} Try / catch
try {
await vibe.spawn(session, { cli, prompt });
} catch (err) {
if (err instanceof ToolError && err.message.includes("async execution")) {
throw new Error("Enable background job support on this session to use vibe mode");
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: SDK embeddings that omit the async job manager wiring; headless/one-shot runs where background jobs are disabled; tests constructing minimal ToolSession doubles.
Related errors
- No session - local:// unavailable
- Vibe tools are unavailable in this session.
- Async bash execution is disabled. Enable async.enabled to us
- Vibe sessions require a stable parent session id.
- operation canceled
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/4f428d2717ab5ba1.
Report an issue: GitHub.