affaan-m/ECC · error · Error
Codex cannot guarantee tool-less review; required stable…
Error message
Codex ${versionMatch[1]} cannot guarantee tool-less review; required stable feature toggles unavailable: ${unavailable.join(', ')} What it means
Even with the right Codex version, verifyToollessSupport() requires every feature in REQUIRED_TOOLLESS_FEATURES (apps, hooks, multi_agent, etc.) to report stage 'stable' in `codex features list`. If any feature is experimental, under development, deprecated, removed, or missing, this error is thrown listing the unavailable toggles, because tool-less (feature-disabled) review can no longer be guaranteed.
Solutions
- Run `codex features list` and check the stage column for each feature named in the error
- Install exactly the supported codex-cli 0.146.0 where all listed toggles are stable
- If a feature was renamed upstream, update REQUIRED_TOOLLESS_FEATURES in review-with-codex.js to the new name
- Skip tool-less review or wait until upstream restores the features to stable
Example fix
// before (features list shows) hooks experimental true // after npm install -g @openai/codex@0.146.0 $ codex features list hooks stable true
Defensive patterns
Strategy: try-catch
Validate before calling
const { execSync } = require('child_process');
const { REQUIRED_TOOLLESS_FEATURES } = require('./review-with-codex');
function requiredFeaturesStable() {
const out = execSync('codex features list', { encoding: 'utf8' });
const stages = new Map();
for (const line of out.split('\n')) {
const m = line.trim().match(/^(\S+)\s+(stable|under development|experimental|deprecated|removed)\s+(true|false)$/);
if (m) stages.set(m[1], m[2]);
}
return REQUIRED_TOOLLESS_FEATURES.every((f) => stages.get(f) === 'stable');
} Try / catch
try {
verifyToollessSupport();
} catch (err) {
if (err.message.includes('required stable feature toggles unavailable')) {
console.error('Tool-less review unsupported on this Codex build:', err.message);
// fall back to a supervised review path
} else throw err;
} Prevention
- Review `codex features list` after every Codex upgrade
- Stay on the pinned codex-cli version where all toggles are stable
- Subscribe to Codex release notes for feature stage changes
- Provide a fallback review mode when toggles are not stable
When it happens
Trigger: verifyToollessSupport() runs `codex features list`; REQUIRED_TOOLLESS_FEATURES.filter() finds features whose parsed stage !== 'stable' — e.g. a feature became 'experimental' or disappeared entirely from the listing.
Common situations: Codex team demoted a feature stage in a patch release; a feature was renamed/removed so the Map lookup misses; running against a build with features compiled out.
Related errors
- Codex version could not be verified for tool-less review
- Codex probe failed ` : ''}
- Codex rollout session not found
- [ecc-codex] WARNING
- [ecc-mcp] WARNING
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/822c553ac3cea459.
Report an issue: GitHub.
Appendix: source
Thrown at skills/council-multi-model/scripts/review-with-codex.js:163
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'
);
if (unavailable.length > 0) {
throw new Error(
`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 = {}) {View on GitHub (pinned to 8321021c54)