can1357/oh-my-pi · error
ACP session fork is unavailable while a prompt is in progres
Error message
ACP session fork is unavailable while a prompt is in progress: ${sessionId} What it means
Thrown by #resolveForkSourceSessionPath when a fork is requested for a loaded session whose prompt turn is still in flight. Forking mid-turn would copy an incoherent, partially-written conversation state, so the agent refuses while a prompt is running.
Source
Thrown at packages/coding-agent/src/modes/acp/acp-agent.ts:1396
if (!record) {
throw new Error(`Unsupported ACP session: ${sessionId}`);
}
return record;
}
#assertMatchingCwd(session: AgentSession, cwd: string): void {
const expected = path.resolve(cwd);
const actual = path.resolve(session.sessionManager.getCwd());
if (actual !== expected) {
throw new Error(`ACP session ${session.sessionId} is already loaded for ${actual}, not ${expected}`);
}
}
async #resolveForkSourceSessionPath(sessionId: string): Promise<string> {
const loaded = this.#sessions.get(sessionId);
if (loaded) {
if (isPromptTurnInFlight(loaded.promptTurn)) {
throw new Error(`ACP session fork is unavailable while a prompt is in progress: ${sessionId}`);
}
await loaded.session.sessionManager.flush();
const sessionPath = loaded.session.sessionManager.getSessionFile();
if (!sessionPath) {
throw new Error(`ACP session cannot be forked before it is persisted: ${sessionId}`);
}
return sessionPath;
}
const storedSession = await this.#findStoredSessionById(sessionId);
if (!storedSession) {
throw new Error(`ACP session not found: ${sessionId}`);
}
return storedSession.path;
}
async #handlePromptEvent(record: ManagedSessionRecord, event: AgentSessionEvent): Promise<void> {
const promptTurn = record.promptTurn;View on GitHub (pinned to 9690622007)
Solutions
- Wait for the current prompt turn to finish (await the prompt response / completion notification) before forking.
- Abort the in-flight prompt (session/cancel) first, then fork.
- Serialize client operations so fork requests are queued after prompt turns.
Example fix
// before
await forkSession({ sessionId });
// after
await cancelIfBusy(sessionId);
await waitForTurnComplete(sessionId);
await forkSession({ sessionId }); Defensive patterns
Strategy: validation
Validate before calling
// track turn state client-side and only fork when idle
if (turnInFlight(sessionId)) {
await waitForTurnCompletion(sessionId); // or await agent.cancel({ sessionId })
}
await agent.fork({ sessionId }); Try / catch
try {
await agent.fork({ sessionId });
} catch (err) {
if (err.message.includes("while a prompt is in progress")) {
await agent.cancel({ sessionId });
await agent.fork({ sessionId });
} else throw err;
} Prevention
- Serialize fork requests after prompt completion events.
- Abort hung prompts before administrative operations.
- Guard UI automation so fork buttons are disabled while streaming.
When it happens
Trigger: ACP session/fork request targeting a session where a prompt has been submitted and not yet completed/aborted (record.promptTurn is in flight).
Common situations: Client fires fork concurrently with a long-running prompt; UI automation forks on a timer while a turn streams; a previous prompt hung and was never aborted.
Related errors
- ACP session fork was cancelled: ${params.sessionId}
- ACP session fork failed: ${params.sessionId}
- ACP session cannot be forked before it is persisted: ${sessi
- native spelling thread stopped
- Agent is already processing. Use steer() or followUp() to qu
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2670bd6525dd276f.
Report an issue: GitHub.