openclaw/openclaw · error

Codex settled-turn projection found oversized ${label}

Error message

Codex settled-turn projection found oversized ${label}

What it means

Thrown by readBoundedText when a text field in the projected transcript exceeds MAX_TEXT_BYTES (64 KiB). The projection caps every individual text field so a single oversized user/assistant/tool string cannot blow the bounded turn's history payload.

Source

Thrown at extensions/codex/src/app-server/settled-turn-projection.ts:34

  calls: ProjectedToolReference[];
  results: ProjectedToolReference[];
  bytes: number;
};

function readNonEmptyString(value: unknown): string | undefined {
  return typeof value === "string" ? value.trim() || undefined : undefined;
}

function readBoundedText(
  value: unknown,
  label: string,
  maxBytes = MAX_TEXT_BYTES,
): string | undefined {
  if (typeof value !== "string" || !value.trim()) {
    return undefined;
  }
  if (Buffer.byteLength(value, "utf8") > maxBytes) {
    throw new Error(`Codex settled-turn projection found oversized ${label}`);
  }
  return value;
}

function requireBoundedText(value: unknown, label: string, maxBytes = MAX_TEXT_BYTES): string {
  const text = readBoundedText(value, label, maxBytes);
  if (!text) {
    throw new Error(`Codex settled-turn projection found empty ${label}`);
  }
  return text;
}

function responseItemBytes(item: JsonValue): number {
  return Buffer.byteLength(JSON.stringify(item), "utf8");
}

function requireCallId(value: unknown): string {
  const callId = readNonEmptyString(value);

View on GitHub (pinned to 01804a7531)

Solutions

  1. Identify which label (user text, assistant text, tool result text, tool arguments, tool result output) tripped the cap — it is interpolated into the message.
  2. Truncate or summarize the offending payload at its producer (the tool or channel adapter) before it reaches the transcript.
  3. If a larger cap is genuinely needed, raise MAX_TEXT_BYTES deliberately and re-check MAX_PROJECTION_BYTES budgeting.

Example fix

// before: tool returns a 200 KiB log dump
const text = fs.readFileSync(hugeLog).toString();

// after: cap at the producer
const MAX = 60 * 1024;
const text = fs.readFileSync(hugeLog, { encoding: "utf8" }).slice(0, MAX);
Defensive patterns

Strategy: validation

Validate before calling

const MAX_TEXT_BYTES = 64 * 1024;

function fitsTextByteLimit(value: unknown): boolean {
  return typeof value === "string" && Buffer.byteLength(value, "utf8") <= MAX_TEXT_BYTES;
}

// before projection, truncate oversized producers
if (!fitsTextByteLimit(textField)) textField = textField.slice(0, MAX_TEXT_BYTES / 2);

Type guard

function isBoundedText(value: unknown, maxBytes = 64 * 1024): value is string {
  return typeof value === "string" && Buffer.byteLength(value, "utf8") <= maxBytes;
}

Prevention

When it happens

Trigger: Projecting a user message, assistant text, or tool result whose text field is over 64 KiB; a tool result that dumped a large log/fixture into its text content; an upstream user message that inlined a huge base64 or log blob as text.

Common situations: Tool that returns a full file or log dump as text; a channel that forwards an oversized attachment body as a text part; a model that produced a very long assistant turn before compaction.

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/7797a88beb4040a2. Report an issue: GitHub.