affaan-m/ECC · error · Error
review packet is empty
Error message
review packet is empty
What it means
runReview() validates the review packet before invoking Codex. A packet that is empty or contains only whitespace fails `!prompt.trim()` and throws 'review packet is empty'. The script refuses to send a useless empty prompt to the external model.
Solutions
- Ensure the review packet (stdin or the prompt argument) contains non-whitespace content before calling runReview
- Check the upstream command that generates the packet actually produced output (e.g. `git diff` in a repo with changes)
- Guard the caller: `if (!packet.trim()) { skip review }` before invoking
- When piping, verify you used the correct file/variable and not an uninitialized one
Example fix
// before
const review = runReview(fs.readFileSync('packet.txt', 'utf8'), options);
// after
const packet = fs.readFileSync('packet.txt', 'utf8');
if (!packet.trim()) throw new Error('packet.txt is empty; nothing to review');
const review = runReview(packet, options); Defensive patterns
Strategy: validation
Validate before calling
function isNonEmptyPacket(prompt) {
return typeof prompt === 'string' && prompt.trim().length > 0;
}
if (!isNonEmptyPacket(packet)) throw new Error('review packet is empty'); Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
return runReview(prompt, options);
} catch (err) {
if (err.message === 'review packet is empty') {
console.error('Nothing to review: packet was blank');
return null;
}
throw err;
} Prevention
- Always check packet.trim().length before invoking external review
- Verify upstream generators (diff/log commands) exited successfully
- Never pipe from commands that can silently produce empty output without checking
- Add a unit test asserting runReview rejects blank packets
When it happens
Trigger: runReview(prompt, options) called with prompt = '' or a whitespace-only string (e.g. '\n', ' '); in the CLI path this happens when stdin delivered no bytes or only whitespace.
Common situations: Piping an empty file or an empty command substitution into the script (`echo -n '' | review-with-codex.js ...`); an upstream step that produced no diff/notes; a variable holding the packet that was never populated.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- at least one explicit seed is required
- At least one guided harness must be selected
- at least one non-empty
- at least one placement is required
- At least one video is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/4222cfe9c33d741f.
Report an issue: GitHub.
Appendix: source
Thrown at skills/council-multi-model/scripts/review-with-codex.js:182
`Codex ${versionMatch[1]} cannot guarantee tool-less review; `
+ `required stable feature toggles unavailable: ${unavailable.join(', ')}`
);
}
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');
View on GitHub (pinned to 8321021c54)