paperclipai/paperclip · warning

Attempt journal limit reached; stop provider dispatch

Error message

Attempt journal limit reached; stop provider dispatch

What it means

AttemptJournal enforces a hard size cap (default 64 MiB via maxBytes). Before every append it checks whether writing the serialized value would exceed the cap and, if so, throws this error explicitly instructing the caller to stop provider dispatch. The journal is a safety valve to prevent unbounded disk growth from runaway agent/provider output.

Source

Thrown at packages/paperclip-runner/src/evals/attempt-journal.ts:13

import { closeSync, constants, fsyncSync, openSync, writeSync } from "node:fs";

/** Controller-owned evidence outside disposable server storage. No credentials. */
export class AttemptJournal {
  #fd: number | null;
  #bytes = 0;
  constructor(path: string, readonly maxBytes = 64 * 1024 * 1024) {
    this.#fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, 0o600);
  }
  append(value: unknown): void {
    if (this.#fd === null) throw new Error("Attempt journal is closed");
    const bytes = Buffer.from(JSON.stringify(value) + "\n");
    if (this.#bytes + bytes.length > this.maxBytes) throw new Error("Attempt journal limit reached; stop provider dispatch");
    let offset = 0;
    while (offset < bytes.length) offset += writeSync(this.#fd, bytes, offset, bytes.length - offset);
    fsyncSync(this.#fd);
    this.#bytes += bytes.length;
  }
  close(): void {
    if (this.#fd !== null) closeSync(this.#fd);
    this.#fd = null;
  }
}

View on GitHub (pinned to 01ad858492)

Solutions

  1. Stop further provider dispatch when this error is thrown — that is the contract; fail the attempt gracefully.
  2. Construct AttemptJournal with a larger maxBytes if the workload legitimately needs more (new AttemptJournal(path, 256 * 1024 * 1024)).
  3. Reduce appended payload size: truncate/summarize large fields before journaling.
  4. Catch this specific error in the dispatch loop and break out cleanly instead of propagating as a crash.

Example fix

// before
journal.append({ output: giantModelResponse });
// after
const summarized = { output: giantModelResponse.slice(0, 10_000), truncated: true };
try { journal.append(summarized); } catch (e) {
  if ((e as Error).message.startsWith('Attempt journal limit reached')) break; // stop dispatch
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const approx = Buffer.byteLength(JSON.stringify(value)) + 1;
if (journalBytesWritten + approx > MAX_JOURNAL_BYTES) throw new Error('would exceed journal cap; stop dispatch now');

Try / catch

try {
  journal.append(entry);
} catch (err) {
  if ((err as Error).message.startsWith('Attempt journal limit reached')) {
    logger.error('journal cap hit; aborting provider dispatch');
    break; // stop dispatch loop as the error instructs
  }
  throw err;
}

Prevention

When it happens

Trigger: Appending very large JSON values (huge model outputs, base64 blobs) or a very high number of append calls during a single attempt until this.#bytes + bytes.length exceeds maxBytes.

Common situations: An agent looping and producing endless events recorded to the journal; verbose provider payloads logged per-request; running long evals where 64 MiB of JSONL is reached; constructing the journal with a small custom maxBytes.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/c09ce7fa3fcfb0c8. Report an issue: GitHub.