affaan-m/ECC · error · Error

review packet exceeds ${MAX_PROMPT_BYTES} bytes

Error message

review packet exceeds ${MAX_PROMPT_BYTES} bytes

What it means

runReview refuses to forward a review packet larger than MAX_PROMPT_BYTES (65536 bytes, i.e. 64 KiB) to the external Codex CLI. The size is measured with Buffer.byteLength(prompt,'utf8') so multibyte content counts correctly. This is a hard safety cap that bounds what is shipped to OpenAI and keeps the subprocess input sane; it fires before any codex process is spawned.

Source

Thrown at skills/council-multi-model/scripts/review-with-codex.js:184

    );
  }
  return versionMatch[1];
}

function buildEnvironment(sourceEnv = process.env) {
  const allowed = [
    'PATH', 'HOME', 'USERPROFILE', 'CODEX_HOME',
    'TMPDIR', 'TMP', 'TEMP', 'SystemRoot', 'ComSpec', 'PATHEXT',
  ];
  return Object.fromEntries(
    allowed.filter((name) => sourceEnv[name]).map((name) => [name, sourceEnv[name]])
  );
}

function runReview(prompt, options, dependencies = {}) {
  if (!prompt.trim()) throw new Error('review packet is empty');
  if (Buffer.byteLength(prompt, 'utf8') > MAX_PROMPT_BYTES) {
    throw new Error(`review packet exceeds ${MAX_PROMPT_BYTES} bytes`);
  }
  if (!options.consent) throw new Error('OpenAI transfer consent is required');
  if (options.timeoutMs < 10_000 || options.timeoutMs > MAX_TIMEOUT_MS) {
    throw new Error('timeout is outside the 10-120 second safety range');
  }

  const spawn = dependencies.spawnSync || spawnSync;
  const environment = buildEnvironment(dependencies.env || process.env);
  const verifySupport = dependencies.verifyToollessSupport || verifyToollessSupport;
  verifySupport({ spawnSync: spawn, env: environment });
  const makeTemp = dependencies.mkdtempSync || fs.mkdtempSync;
  const readFile = dependencies.readFileSync || fs.readFileSync;
  const remove = dependencies.rmSync || fs.rmSync;
  const tempDir = makeTemp(path.join(os.tmpdir(), 'ecc-council-review-'));
  const outputFile = path.join(tempDir, 'last-message.txt');

  try {
    const result = spawn('codex', buildCodexArgs(tempDir, outputFile), {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Measure the packet first: if (Buffer.byteLength(packet,'utf8') > 65536) trim it before calling runReview.
  2. Strip boilerplate, file headers, and unrelated context from the packet until it fits under 64 KiB.
  3. Split one oversized review into several smaller packets and call runReview per chunk.
  4. Drop base64/binary payloads and summarize them as text instead.

Example fix

// before
const review = runReview(hugeDiff + hugeLog, opts);

// after
const MAX = 64 * 1024;
let packet = hugeDiff + hugeLog;
if (Buffer.byteLength(packet, 'utf8') > MAX) {
  packet = packet.slice(0, MAX); // or split into multiple runReview calls
}
const review = runReview(packet, opts);
Defensive patterns

Strategy: validation

Validate before calling

const MAX_PROMPT_BYTES = 64 * 1024;
function fitsReviewBudget(packet) {
  return Buffer.isBuffer(packet)
    ? packet.length <= MAX_PROMPT_BYTES
    : Buffer.byteLength(packet, 'utf8') <= MAX_PROMPT_BYTES;
}
// before calling runReview:
if (!fitsReviewBudget(packet)) {
  throw new Error(`packet is ${Buffer.byteLength(packet,'utf8')} bytes; trim to <= ${MAX_PROMPT_BYTES}`);
}

Prevention

When it happens

Trigger: Calling runReview(prompt, options) (or runStdinReview, which delegates to it) where Buffer.byteLength(prompt,'utf8') strictly exceeds 65536. Note runStdinReview also short-circuits at the stdin-accumulation layer with a different message, but any direct programmatic call with an oversized joined string hits this throw at line 184.

Common situations: Piping a large git diff, build log, or concatenated source tree into the review packet; base64-encoding a binary artifact into the prompt; joining many review contexts without measuring; tests that construct a huge fixture string.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/6273c831f52a6605. Report an issue: GitHub.