can1357/oh-my-pi · error · Error
Codex session ${info.id} at ${info.path} is empty or malform
Error message
Codex session ${info.id} at ${info.path} is empty or malformed What it means
CodexSessionStore.load() successfully read the rollout file but readJsonLines yielded zero records, meaning the file is empty or every line failed parsing. Thrown to distinguish 'readable but no usable content' from a hard read failure.
Source
Thrown at packages/coding-agent/src/session/codex-session-store.ts:551
modified,
});
}
sessions.sort(
(left, right) => right.modified.getTime() - left.modified.getTime() || left.id.localeCompare(right.id),
);
return sessions;
}
/** Converts one Codex rollout into a non-persistent OMP session. */
async load(info: ForeignSessionInfo): Promise<SessionManager> {
if (info.source !== "codex") throw new Error(`Cannot load ${info.source} session with CodexSessionStore`);
let records: Record<string, unknown>[];
try {
records = await readJsonLines(info.path);
} catch (error) {
throw new Error(`Unable to read Codex session ${info.id} at ${info.path}`, { cause: error });
}
if (records.length === 0) throw new Error(`Codex session ${info.id} at ${info.path} is empty or malformed`);
const metadata = records.find(record => record.type === "session_meta" && isRecord(record.payload));
const cwd =
metadata && isRecord(metadata.payload) ? (stringField(metadata.payload, "cwd") ?? info.cwd) : info.cwd;
const manager = SessionManager.inMemory(cwd);
const canonical = canonicalTexts(records);
const converted: ConvertedRecord[] = [];
const toolNames = new Map<string, string>();
let model = "codex";
let fallbackTimestamp = info.created.getTime();
let title = info.title;
for (const record of records) {
const timestamp = timestampMillis(record.timestamp, fallbackTimestamp);
fallbackTimestamp = Math.max(fallbackTimestamp + 1, timestamp);
if (!isRecord(record.payload)) continue;
let item: ConvertedRecord | undefined;
if (record.type === "turn_context") {View on GitHub (pinned to 9690622007)
Solutions
- Check file size (ls -l info.path) — a 0-byte file means Codex never wrote the session
- Re-run the Codex session to regenerate a real rollout, then re-list and load
- Remove the empty/stub file so stale listings stop offering it
- Point info.path at the actual rollout file if the wrong path was passed
Example fix
// before
const manager = await codexStore.load(info);
// after
const stat = await fs.stat(info.path);
if (stat.size === 0) throw new Error(`Codex rollout is empty: ${info.path}`);
const manager = await codexStore.load(info); Defensive patterns
Strategy: validation
Validate before calling
import * as fs from "node:fs";
export function isNonEmptyCodexRollout(path: string): boolean {
try {
const content = fs.readFileSync(path, 'utf8');
return content.split('\n').some(line => line.trim().length > 0);
} catch {
return false;
}
} Type guard
function isEmptyOrMalformedCodexSession(err: unknown): boolean {
return err instanceof Error && /is empty or malformed$/.test(err.message);
} Prevention
- Check the rollout has content before offering a session for resume
- Delete zero-byte stub files left by crashed Codex runs
- Pass info.path from store.list() output rather than constructing paths by hand
When it happens
Trigger: Calling load(info) on a zero-byte rollout file, a file containing only blank lines, or a file whose lines are all malformed JSON so readJsonLines returns an empty array.
Common situations: Codex created the session file but crashed before writing the session_meta line; disk-full left a stub file; a sync tool synced an empty placeholder; the wrong file was passed as info.path.
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
- Claude session ${info.id} contains no readable records
- Cannot load ${info.source} session with CodexSessionStore
- Unable to read Codex session ${info.id} at ${info.path}
- Cannot resume session "${resolvedSessionFile}": the session
- Replacement text is not valid UTF-8: {err}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ec3f7ef49c2f0ef9.
Report an issue: GitHub.