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

  1. Wait for the current prompt turn to finish (await the prompt response / completion notification) before forking.
  2. Abort the in-flight prompt (session/cancel) first, then fork.
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/2670bd6525dd276f. Report an issue: GitHub.