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
- Retry the review once — empty responses are often transient.
- Inspect the codex run manually to see whether it produced any stdout/stderr commentary.
- Loosen or review the buildCodexArgs constraints (e.g. --ignore-rules, --skip-git-repo-check) only if appropriate, to avoid refusals.
- 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
- Retry once on empty-response errors; they are frequently transient.
- Keep the packet non-empty and coherent after trimming.
- Reproduce manually with the same args to see whether codex is refusing the content.
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
- Codex returned no final response: ${error.message}
- Invalid ${flag}: expected a single cache path segment
- Unknown argument: ${arg}
- Missing value for ${arg}
- Failed to read ${filePath}: ${error.message}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/d721c3c95f9d18b6.
Report an issue: GitHub.