affaan-m/ECC · error · Error

Codex returned an empty final response

Error message

Codex returned an empty final response

What it means

The --output-last-message file was read successfully but contained only whitespace after trim. runReview treats an empty critique as an unusable result and throws. This means codex completed and wrote the file but produced no actual review text.

Source

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

    });

    if (result.error) {
      if (result.error.code === 'ETIMEDOUT') throw new Error('Codex review timed out');
      if (result.error.code === 'ENOENT') throw new Error('Codex CLI is not installed');
      throw new Error(`Codex invocation failed: ${result.error.message}`);
    }
    if (result.status !== 0) {
      const detail = (result.stderr || '').trim().split('\n').slice(-1)[0];
      throw new Error(`Codex review failed${detail ? `: ${detail}` : ''}`);
    }

    let text;
    try {
      text = readFile(outputFile, 'utf8').trim();
    } catch (error) {
      throw new Error(`Codex returned no final response: ${error.message}`);
    }
    if (!text) throw new Error('Codex returned an empty final response');
    return `${providerLabel(options.hostProvider)}\n${text}`;
  } finally {
    remove(tempDir, { recursive: true, force: true });
  }
}

function runStdinReview(options, dependencies = {}) {
  const stdin = dependencies.stdin || process.stdin;
  const stdout = dependencies.stdout || process.stdout;
  const stderr = dependencies.stderr || process.stderr;
  const review = dependencies.runReview || runReview;
  const setExitCode = dependencies.setExitCode || ((code) => { process.exitCode = code; });
  const chunks = [];
  let promptBytes = 0;
  let promptOverflow = false;
  stdin.setEncoding('utf8');
  stdin.on('data', (chunk) => {
    if (promptOverflow) return;

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Retry the review once — empty responses are often transient.
  2. Inspect the codex run manually to see whether it produced any stdout/stderr commentary.
  3. Loosen or review the buildCodexArgs constraints (e.g. --ignore-rules, --skip-git-repo-check) only if appropriate, to avoid refusals.
  4. Ensure the prompt is non-empty and coherent after trimming.
Defensive patterns

Strategy: validation

Validate before calling

// no pre-check possible for an empty model response; instead validate inputs that tend to cause it
if (!packet.trim()) {
  throw new Error('Cannot request a review for an empty packet.');
}

Try / catch

try {
  return runReview(packet, options);
} catch (error) {
  if (error.message === 'Codex returned an empty final response' && attempt < MAX_RETRIES) {
    await backoff(attempt);
    return runReview(packet, options);
  }
  throw error;
}

Prevention

When it happens

Trigger: readFile succeeds and text.trim() === '' at line 228. The output file exists but is empty or whitespace-only.

Common situations: The model returned a blank/refused response; output was redirected elsewhere by config; the prompt caused codex to emit nothing; a codex quirk writing an empty last-message on certain exits.

Related errors


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