can1357/oh-my-pi · error

ACP session cannot be forked before it is persisted: ${sessi

Error message

ACP session cannot be forked before it is persisted: ${sessionId}

What it means

Thrown by #resolveForkSourceSessionPath when the loaded session has no session file: after flushing, sessionManager.getSessionFile() still returns nothing, meaning the session was never persisted and there is nothing on disk to fork from. Fork requires a source file to copy.

Source

Thrown at packages/coding-agent/src/modes/acp/acp-agent.ts:1401

	#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;
		if (!promptTurn || promptTurn.settled || promptTurn.cancelRequested) {
			return;
		}

		if (event.type === "tool_execution_start" || event.type === "tool_execution_update") {

View on GitHub (pinned to 9690622007)

Solutions

  1. Ensure the session is configured with persistence enabled so a session file is created.
  2. Send at least one turn (or trigger a flush/save) before forking.
  3. Check disk space/permissions in the sessions storage directory if flush is failing to materialize the file.

Example fix

// before
const session = await createSession({ cwd, persist: false });
await forkSession({ sessionId: session.sessionId });
// after
const session = await createSession({ cwd, persist: true });
await session.prompt("init"); // ensure state is persisted
await forkSession({ sessionId: session.sessionId });
Defensive patterns

Strategy: validation

Validate before calling

// fork requires a persisted session file
const file = session.sessionManager.getSessionFile();
if (!file) throw new Error("session not persisted yet; run a turn or enable persistence before forking");

Try / catch

try {
  await agent.fork({ sessionId });
} catch (err) {
  if (err.message.includes("before it is persisted")) {
    // enable persistence or send a turn first, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: Forking a session created with persistence disabled, or a brand-new session whose first write to disk failed/hasn't happened, so no session file exists.

Common situations: Sessions running with ephemeral/no-persist configuration; disk-full or permissions issues preventing the session file from being written; forking immediately after session creation before any persisted turn.

Related errors


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