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
- Verify the file is an omp session JSONL file and starts with a valid header JSON line.
- Restore the session file from backup or version control.
- Repair or reconstruct the header line manually (off a known-good session file as a template) at your own risk.
- 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
- Never hand-edit session JSONL files.
- Ensure the writing process completes (avoid killing the process mid-write, watch disk space).
- Keep backups of session files; validate header before resuming after a crash.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- HTTP ${response.status} resuming MCP SSE stream: ${text}
- Claude session ${info.id} contains no readable records
- Codex session ${info.id} at ${info.path} is empty or malform
- Replacement text is not valid UTF-8: {err}
- V2 compaction stream parse failed: ${err instanceof Error ?
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e6684771f2a0eb16.
Report an issue: GitHub.