can1357/oh-my-pi · critical · AggregateError
Session append failed and its partial bytes could not be rol
Error message
Session append failed and its partial bytes could not be rolled back
What it means
When appendSync's write fails, SessionStorage tries ftruncateSync to roll the session file back to its original size so no partial JSONL bytes corrupt it. If the write AND the rollback both fail, it throws an AggregateError containing both errors with this message, because the session file is now left in a partially-written state that cannot be safely repaired automatically.
Source
Thrown at packages/coding-agent/src/session/session-storage.ts:146
}
#writeNow(line: string): void {
const originalSize = fs.fstatSync(this.#fd).size;
const buf = Buffer.from(line, "utf-8");
let offset = 0;
try {
while (offset < buf.length) {
const written = fs.writeSync(this.#fd, buf, offset, buf.length - offset);
if (written === 0) {
throw new Error("Short write");
}
offset += written;
}
} catch (writeError) {
try {
fs.ftruncateSync(this.#fd, originalSize);
} catch (rollbackError) {
throw new AggregateError(
[toError(writeError), toError(rollbackError)],
"Session append failed and its partial bytes could not be rolled back",
);
}
throw writeError;
}
}
appendSync(line: string): void {
if (this.#closed) throw new Error("Writer closed");
if (this.#error) throw this.#error;
// Write in-body so software crash after the call still sees the entry.
// Microtask batching used to leave completed transcript lines only in
// memory until the next event-loop turn; process crash then lost every
// post-checkpoint event. flush/flushSync remain no-op drains (no fsync).
try {
this.#writeNow(line);
} catch (err) {View on GitHub (pinned to 9690622007)
Solutions
- Free disk space or restore write access to the volume immediately — the session file may contain a partial line.
- Manually inspect the session .jsonl file and delete the trailing incomplete line to restore a valid JSONL stream.
- If the volume went read-only, remount it read-write (or move the session directory to a healthy disk) before continuing.
- Copy/backup the session file before any manual repair, then let the app recreate entries from the last valid line.
Example fix
// manual repair of the corrupted tail
node -e "
const fs = require('fs');
const p = process.argv[1];
const lines = fs.readFileSync(p, 'utf8').split('\n');
while (lines.length && (!lines[lines.length-1] || !safeJson(lines[lines.length-1]))) lines.pop();
fs.writeFileSync(p, lines.join('\n') + '\n');
" session-file.jsonl Defensive patterns
Strategy: try-catch
Validate before calling
const s = await statfs(sessionDir);
if (s.bavail * s.bsize < 10 * 1024 * 1024) {
// refuse to run sessions on a nearly-full disk
throw new Error("Insufficient disk space for session storage");
} Type guard
function isAggregateWriteFailure(err: unknown): err is AggregateError {
return err instanceof AggregateError &&
err.message.includes("partial bytes could not be rolled back");
} Try / catch
try {
storage.appendSync(line);
} catch (err) {
if (isAggregateWriteFailure(err)) {
for (const e of err.errors) logger.error("Session append + rollback failed", { e });
// session file may hold a partial line — quarantine/validate it before further use
} else throw err;
} Prevention
- Keep ample free space on the session volume; truncation itself needs write access.
- Never let the volume go read-only mid-session.
- Back up session files before manual repair of a partial line.
- Treat this error as data-integrity critical: validate the JSONL tail before reading the session.
When it happens
Trigger: writeSync fails (e.g. ENOSPC, EIO) and the subsequent ftruncateSync also fails — typically because the disk is still full (truncate needs a metadata write), the fd is broken, or the filesystem went read-only.
Common situations: Fully saturated disk on a long-running agent session where the original write fails on space and truncation also fails on the same condition; device errors or a volume remounted read-only mid-session.
Related errors
- Unable to read Claude session ${info.id}: ${detail}
- Unable to read Codex session ${info.id} at ${info.path}
- Short write
- Too many levels of symbolic links
- {}: {error}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bfb0afe9c6b9c502.
Report an issue: GitHub.