affaan-m/ECC · error · Error
Codex invocation failed
Error message
Codex invocation failed: ${result.error.message} What it means
This is the catch-all branch for spawnSync result.error codes other than ETIMEDOUT and ENOENT. Node can surface spawn failures such as EACCES (not executable), EPERM, or process-level errors; the library wraps the underlying message in 'Codex invocation failed: <message>' for diagnosis.
Solutions
- Read result.error.message in the thrown text to identify the exact errno code.
- For EACCES: chmod +x the codex binary or reinstall the CLI.
- For EPERM: check antivirus/endpoint policy or sandbox restrictions blocking child process execution.
- Reinstall the Codex CLI if the binary appears corrupted.
- Try invoking `codex --version` in the same shell/environment to reproduce outside the library.
Example fix
// before (binary not executable) -rw-r--r-- codex // after chmod +x $(which codex) # EACCES from spawn resolved
Defensive patterns
Strategy: try-catch
Validate before calling
const check = spawnSync('codex', ['--version']);
if (check.error && check.error.code === 'EACCES') {
throw new Error('codex binary is not executable: chmod +x ' + check.error.path);
} Try / catch
try {
return runReview(opts);
} catch (e) {
if (e.message.startsWith('Codex invocation failed:')) {
const errno = e.message.split(': ')[1];
if (errno === 'EACCES') fixExecutableBit();
if (errno === 'EPERM') warnSandboxBlocked();
}
throw e;
} Prevention
- Keep the Codex CLI installed via the official package manager so permissions are correct.
- Avoid copying binaries across mounts (permissions/exec bits are often lost).
- Test spawns inside the actual runtime environment (container/sandbox) before batch runs.
When it happens
Trigger: spawnSync returns result.error with any code besides 'ETIMEDOUT'/'ENOENT' — e.g. EACCES because the codex binary lacks the execute bit, EPERM from a security policy/sandbox blocking process spawn, or a killed process reported by Node.
Common situations: Codex CLI installed but not executable (permissions lost after copy/mount); corporate endpoint protection blocking spawned node children; running inside a container/sandbox that forbids exec; corrupted CLI install.
Related errors
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/ab225f8fadd8e25e.
Report an issue: GitHub.
Appendix: source
Thrown at skills/council-multi-model/scripts/review-with-codex.js:215
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), {
cwd: tempDir,
env: environment,
input: prompt,
encoding: 'utf8',
timeout: options.timeoutMs,
maxBuffer: 1024 * 1024,
windowsHide: true,
});
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 });
}
}View on GitHub (pinned to 8321021c54)