affaan-m/ECC · error · Error
Codex version could not be verified for tool-less review
Error message
Codex version could not be verified for tool-less review
What it means
verifyToollessSupport() parses the output of `codex --version` with the regex /^codex-cli\s+([^\s]+)$/m. If no line in the CLI output matches that shape, the script cannot determine the installed Codex version and throws this error rather than risk running a tool-less review against an unknown CLI. The expected output format is a line like `codex-cli 0.146.0`.
Solutions
- Run `codex --version` and confirm the output contains a line starting with `codex-cli ` followed by a version
- Install the exact supported version (`npm install -g @openai/codex@0.146.0`) whose banner matches the expected format
- Remove CLI wrappers/shims that alter the version output; call the real binary directly
- If a legitimate newer Codex changed the banner, update the script's version regex
Example fix
// before $ codex --version OpenAI Codex 0.150.0 // banner format changed // after npm install -g @openai/codex@0.146.0 $ codex --version codex-cli 0.146.0 // matches /^codex-cli\s+([^\s]+)$/m
Defensive patterns
Strategy: validation
Validate before calling
const { execSync } = require('child_process');
function codexVersionParses() {
const out = execSync('codex --version', { encoding: 'utf8' });
return /^codex-cli\s+([^\s]+)$/m.test(out.trim());
} Type guard
function hasKnownVersion(versionText) {
return typeof versionText === 'string' && /^codex-cli\s+([^\s]+)$/m.test(versionText);
} Try / catch
try {
verifyToollessSupport();
} catch (err) {
if (err.message.includes('could not be verified')) {
console.error('Unrecognized `codex --version` output:', err.message);
} else throw err;
} Prevention
- Check `codex --version` output format after any Codex upgrade
- Avoid wrapper shims that prepend extra output to the binary
- Run the binary directly rather than through npx/snap layers
- Add a CI assertion that the version banner matches the expected regex
When it happens
Trigger: verifyToollessSupport() runs successfully but the trimmed stdout of `codex --version` does not contain a line matching `codex-cli <version>` — e.g. output was empty, a shell wrapper echoed extra text, or a newer/older Codex release changed the version banner format.
Common situations: A Codex CLI installed via a wrapper (e.g. snap, npx shim, Homebrew) that prints a preamble; Codex versions that renamed the banner (no `codex-cli` prefix); stderr vs stdout mixing issues; extremely old or nightly builds.
Related errors
- Codex probe failed ` : ''}
- Codex cannot guarantee tool-less review; required stable…
- unsupported Codex version
- Agents directory not found
- --all-harnesses and --harness are mutually exclusive.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/aad6804780fff644.
Report an issue: GitHub.
Appendix: source
Thrown at skills/council-multi-model/scripts/review-with-codex.js:142
throw new Error(`Codex ${label} probe failed${detail ? `: ${detail}` : ''}`);
}
return (result.stdout || '').trim();
}
function verifyToollessSupport(dependencies = {}) {
const spawn = dependencies.spawnSync || spawnSync;
const options = {
cwd: os.tmpdir(),
env: buildEnvironment(dependencies.env || process.env),
encoding: 'utf8',
timeout: 5_000,
maxBuffer: 256 * 1024,
windowsHide: true,
};
const versionText = probeCodex(spawn, ['--version'], options, 'version');
const versionMatch = versionText.match(/^codex-cli\s+([^\s]+)$/m);
if (!versionMatch) {
throw new Error('Codex version could not be verified for tool-less review');
}
if (versionMatch[1] !== SUPPORTED_CODEX_VERSION) {
throw new Error(
`unsupported Codex version ${versionMatch[1]}; `
+ `tool-less review requires exactly ${SUPPORTED_CODEX_VERSION}`
);
}
const featuresText = probeCodex(spawn, ['features', 'list'], options, 'feature');
const stages = new Map();
for (const line of featuresText.split('\n')) {
const match = line.trim().match(
/^(\S+)\s+(stable|under development|experimental|deprecated|removed)\s+(true|false)$/
);
if (match) stages.set(match[1], match[2]);
}
const unavailable = REQUIRED_TOOLLESS_FEATURES.filter(
(feature) => stages.get(feature) !== 'stable'View on GitHub (pinned to 8321021c54)