{"record":{"id":"822c553ac3cea459","repo":"affaan-m/ECC","slug":"codex-versionmatch-1-cannot-guarantee-tool-les","errorCode":null,"errorMessage":"Codex ${versionMatch[1]} cannot guarantee tool-less review; required stable feature toggles unavailable: ${unavailable.join(', ')}","messagePattern":"Codex (.+?) cannot guarantee tool-less review; required stable feature toggles unavailable: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/council-multi-model/scripts/review-with-codex.js","lineNumber":163,"sourceCode":"    throw new Error(\n      `unsupported Codex version ${versionMatch[1]}; `\n      + `tool-less review requires exactly ${SUPPORTED_CODEX_VERSION}`\n    );\n  }\n\n  const featuresText = probeCodex(spawn, ['features', 'list'], options, 'feature');\n  const stages = new Map();\n  for (const line of featuresText.split('\\n')) {\n    const match = line.trim().match(\n      /^(\\S+)\\s+(stable|under development|experimental|deprecated|removed)\\s+(true|false)$/\n    );\n    if (match) stages.set(match[1], match[2]);\n  }\n  const unavailable = REQUIRED_TOOLLESS_FEATURES.filter(\n    (feature) => stages.get(feature) !== 'stable'\n  );\n  if (unavailable.length > 0) {\n    throw new Error(\n      `Codex ${versionMatch[1]} cannot guarantee tool-less review; `\n      + `required stable feature toggles unavailable: ${unavailable.join(', ')}`\n    );\n  }\n  return versionMatch[1];\n}\n\nfunction buildEnvironment(sourceEnv = process.env) {\n  const allowed = [\n    'PATH', 'HOME', 'USERPROFILE', 'CODEX_HOME',\n    'TMPDIR', 'TMP', 'TEMP', 'SystemRoot', 'ComSpec', 'PATHEXT',\n  ];\n  return Object.fromEntries(\n    allowed.filter((name) => sourceEnv[name]).map((name) => [name, sourceEnv[name]])\n  );\n}\n\nfunction runReview(prompt, options, dependencies = {}) {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/skills/council-multi-model/scripts/review-with-codex.js#L145-L181","documentation":"Thrown by verifyToollessSupport() after parsing `codex features list` output. For each name in REQUIRED_TOOLLESS_FEATURES (apps, shell_tool, browser_use, unified_exec, etc.), the parsed stage must be 'stable'. Any feature that is missing from the output or staged as 'under development'/'experimental'/'deprecated'/'removed' is collected into `unavailable` and reported. This guarantees the tool-less review cannot accidentally enable a tool.","triggerScenarios":"A Codex 0.146.0 build where one or more of the required feature toggles is not stable, e.g. shell_tool is 'experimental' or browser_use is missing from `codex features list`. The error names the offending features.","commonSituations":"A patched/forked Codex build with different feature stages; a nightly that reclassifies a feature; a feature renamed between builds so the regex no longer matches it (it then counts as unavailable).","solutions":["Run `codex features list` by hand and check the stage column for each named feature.","Reinstall the canonical Codex 0.146.0 build whose features are all stable.","If a feature was legitimately renamed, update REQUIRED_TOOLLESS_FEATURES in the script to match and re-validate."],"exampleFix":"// before\nError: Codex 0.146.0 cannot guarantee tool-less review; required stable feature toggles unavailable: shell_tool, browser_use\n\n// after: reinstall the canonical build and re-check\n$ codex features list | grep -E 'shell_tool|browser_use'\nshell_tool stable true\nbrowser_use stable true","handlingStrategy":"validation","validationCode":"function assertRequiredFeaturesStable(featuresText, required) {\n  const stages = new Map();\n  for (const line of (featuresText || '').split('\\n')) {\n    const m = line.trim().match(/^(\\S+)\\s+(stable|under development|experimental|deprecated|removed)\\s+(true|false)$/);\n    if (m) stages.set(m[1], m[2]);\n  }\n  const missing = required.filter(f => stages.get(f) !== 'stable');\n  if (missing.length) throw new Error(`required features not stable: ${missing.join(', ')}`);\n}","typeGuard":"function allRequiredFeaturesStable(featuresText, required) {\n  const stages = new Map();\n  for (const line of (featuresText || '').split('\\n')) {\n    const m = line.trim().match(/^(\\S+)\\s+(stable|under development|experimental|deprecated|removed)\\s+(true|false)$/);\n    if (m) stages.set(m[1], m[2]);\n  }\n  return required.every(f => stages.get(f) === 'stable');\n}","tryCatchPattern":"try {\n  verifyToollessSupport({ spawnSync });\n} catch (error) {\n  if (/cannot guarantee tool-less review/.test(error.message)) {\n    // reinstall canonical codex build with stable toggles, then retry\n  } else {\n    throw error;\n  }\n}","preventionTips":["Use the canonical Codex 0.146.0 build whose features are all stable.","Do not run a patched/forked Codex for tool-less review unless its feature stages match.","Re-validate the required-feature list whenever Codex is upgraded."],"tags":["runtime","environment","codex","features","verification","tool-less","safety"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}