can1357/oh-my-pi · error · Error

Cannot resume session "${resolvedSessionFile}": the session

Error message

Cannot resume session "${resolvedSessionFile}": the session header is missing or malformed. The file was not modified.

What it means

Thrown when resuming a session file whose header (the JSON metadata block at the top of the JSONL session file) is missing or cannot be parsed. loadSessionFile flags invalidHeader, and resume refuses to proceed without modifying the file, protecting potentially salvageable data from being overwritten by a malformed-header write path.

Source

Thrown at packages/coding-agent/src/session/session-manager.ts:1403

			this.#forceFileCreation = true;
			this.#rewriteRequired = true;
			await this.#rewriteAtomically();
		}
	}
	/** Switch to a different session file (resume / branch). */
	async setSessionFile(sessionFile: string): Promise<void> {
		await this.#setSessionFile(sessionFile);
	}

	async #setSessionFile(sessionFile: string, loadedSession?: SessionLoadResult): Promise<void> {
		await this.#drainAndCloseWriter();
		this.#clearDiskError();
		this.#draftOnlySessionCleanupArmed = false;

		const resolvedSessionFile = path.resolve(sessionFile);
		const loaded = loadedSession ?? (await loadSessionFile(resolvedSessionFile, this.#storage));
		if (loaded.invalidHeader) {
			throw new Error(
				`Cannot resume session "${resolvedSessionFile}": the session header is missing or malformed. The file was not modified.`,
			);
		}

		this.#sessionFile = resolvedSessionFile;
		this.#rememberBreadcrumb(this.#cwd, resolvedSessionFile);

		const { entries: fileEntries, titleSlot } = loaded;
		if (fileEntries.length === 0) {
			// Explicit but empty/missing path (e.g. --session flag): start fresh but
			// keep the requested path and materialize the header immediately.
			this.#resetToNewSession(undefined, resolvedSessionFile);
			this.#forceFileCreation = true;
			await this.#rewriteAtomically();
			this.#fileIsCurrent = true;
			return;
		}

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the file is an omp session JSONL file and starts with a valid header JSON line.
  2. Restore the session file from backup or version control.
  3. Repair or reconstruct the header line manually (off a known-good session file as a template) at your own risk.
  4. Start a new session and re-import needed content from the broken file's message lines.

Example fix

// before: resuming a truncated/edited file
await mgr.resume("session.jsonl"); // invalidHeader
// after: validate header first
const first = readFileSync(file, "utf8").split("\n")[0];
if (JSON.parse(first).type !== "header") await mgr.resume("good-backup.jsonl");
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeSessionFile(path) {
  const first = readFileSync(path, "utf8").split("\n", 1)[0];
  try { return typeof JSON.parse(first) === "object"; } catch { return false; }
}

Type guard

function isValidHeader(line) {
  try { const h = JSON.parse(line); return h != null && typeof h === "object" && h.type === "header"; }
  catch { return false; }
}

Try / catch

try {
  await mgr.resume(file);
} catch (err) {
  if (err.message.includes("header is missing or malformed")) {
    // restore from backup or start a new session; file was NOT modified
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the resume path (loadSession/resume in SessionManager, session-manager.ts:1403) with a path to a file that is empty, truncated mid-write, hand-edited so the header line is missing/invalid JSON, or written by an incompatible older format.

Common situations: Crash or disk-full during the first write of a session; user edited the file; restoring a partial backup; passing the wrong file (e.g. a log or artifacts file) to resume.

Understand the failure class

Related errors


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