can1357/oh-my-pi · error · Error

Failed to persist ${sourceName} session

Error message

Failed to persist ${sourceName} session

What it means

SelectorController throws this when a foreign-source session (e.g. an imported/collab or external provider session) was selected and imported in memory, but persistForeignSession did not yield a session file on disk. The controller cannot resume a session without a backing file, so it aborts the import-and-resume flow. It signals an internal persistence failure, not a user-selection problem.

Source

Thrown at packages/coding-agent/src/modes/controllers/selector-controller.ts:1606

			const foreignByPath = new Map(foreignSessions.map(session => [session.path, session]));
			sessions = foreignSessions.map(foreignSessionInfoToSessionInfo);
			onSelectSession = async session => {
				try {
					await this.ctx.settings.flush();
				} catch (error) {
					this.ctx.showError(
						`Failed to save pending settings: ${error instanceof Error ? error.message : String(error)}`,
					);
					return false;
				}
				const foreignSession = foreignByPath.get(session.path);
				if (!foreignSession) throw new Error(`Selected ${sourceName} session is no longer available`);
				const imported = await persistForeignSession(store, foreignSession, {
					fallbackCwd: this.ctx.sessionManager.getCwd(),
					suppressBreadcrumb: true,
				});
				const sessionFile = imported.getSessionFile();
				if (!sessionFile) throw new Error(`Failed to persist ${sourceName} session`);
				await imported.close();
				return await this.handleResumeSession(sessionFile, { settingsFlushed: true });
			};
			selectorOptions = {
				title: `Import ${sourceName} Session`,
				scopeLabel: false,
				showCwd: true,
			};
		} else {
			const [loadedSessions, pinnedIds] = await Promise.all([
				SessionManager.list(this.ctx.sessionManager.getCwd(), this.ctx.sessionManager.getSessionDir()),
				loadPinnedSessionIds(),
			]);
			sessions = loadedSessions;
			const historyStorage = this.ctx.historyStorage;
			const historyMatcher = historyStorage
				? (query: string) => historyStorage.matchingSessionIds(query)
				: undefined;

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the session storage directory (sessionManager cwd / OMP data dir) is writable and has free space
  2. Check persistForeignSession's store configuration — ensure a FileSessionStorage-backed store is used so a session file is created
  3. Retry the import; if persistent, inspect logs for the underlying persistence error from persistForeignSession
  4. Report the underlying persist failure — getSessionFile() being empty after a successful import is a bug in the import path

Example fix

// before
const imported = await persistForeignSession(store, foreignSession, { fallbackCwd });
const sessionFile = imported.getSessionFile();
// after
const imported = await persistForeignSession(store, foreignSession, { fallbackCwd });
const sessionFile = imported.getSessionFile();
if (!sessionFile) {
  // ensure the store has a writable directory before persisting
  await fs.mkdir(sessionDir, { recursive: true });
  throw new Error(`Failed to persist ${sourceName} session`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const store = new FileSessionStorage({ dir: sessionDir });
await fs.access(sessionDir, fs.constants.W_OK); // storage dir must be writable

Type guard

function hasSessionFile(s: { getSessionFile(): string | undefined }): s is { getSessionFile(): string } {
  return typeof s.getSessionFile() === "string" && s.getSessionFile().length > 0;
}

Try / catch

try {
  const session = await selector.importAndResume(foreignSession);
} catch (err) {
  if (err.message.startsWith("Failed to persist")) {
    ui.showError("Could not write the imported session to disk. Check disk space/permissions and retry.");
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the selector's import flow (via handleSelect in SelectorController) when the imported session's getSessionFile() returns undefined — i.e. persistForeignSession completed but did not write/attach a session file path.

Common situations: Disk write failures or a session store misconfigured so the imported session has no file path; importing a foreign session whose serialization produced no file; running with a session manager pointed at an unwritable directory.

Related errors


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