You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Codex CLI: op=hook_preflight failure new in v0.10.4, and the section header stopped printing #1633
op=hook_preflight is a new failure. On 0.10.3 the same run failed with op=mcp_install plus op=legacy_hook_cleanup — a different pair.
The Codex CLI: section header stopped printing in the output.
Suspect
PR #1443 (0cf0ccb5, "reconcile normalized Codex hooks", @astandrik) merged into v0.10.4 and is the only change in that area. It reconciles an owned inline hook assignment into the canonical block instead of ignoring it and re-adding alongside, and it refuses genuinely ambiguous TOML without modifying the file.
That refusal path is the obvious candidate: a config the previous code would have rewritten may now be classified as ambiguous and declined. If so the behaviour is arguably correct — we stopped silently mangling a file — but the reporting is not, because "ambiguous, refusing to touch it" and "failed to write" are indistinguishable in the current message.
Not yet bisected. Worth doing that before assuming, since the vanished section header suggests the flow diverges earlier than the write.
The deeper fix is the editors carrying their own reason out; the TOML editor has the same collapse-to--1 problem as the YAML and JSON ones.
@astandrik — no criticism implied, your PR fixed a real and nasty bug (a duplicated install breaking Codex permanently). This is just the next layer showing through, and if the new behaviour is a deliberate refusal then the fix is to say so rather than to revert.
I traced the missing heading to 0cf0ccb5. The new preflight runs before install_generic_agent_config(), so Codex CLI: is never printed when reconciliation refuses the config.
I reproduced the refusal with an inline hooks.SessionStart value that mixes a CBM-owned command with a foreign command. The reconciler correctly leaves the file byte-identical. The exact reporter config from #1560 is not public, so this is the closest reproducible ownership case rather than proof of the same input.
PR #1638 restores the heading and reports a stable reason such as reason=ambiguous_hook_ownership without weakening the fail-closed behavior. It is the deeper editor-reason follow-up you described; #1629 still adds useful target metadata.
New evidence that sharpens this considerably, from @spam0115 on #1580 (Windows, v0.10.4):
"Even though it already had entries from the recent v0.10.2, it was unable to recognize the entries and reported an error. I had to delete all references to cbm in the toml file by hand."
So hook_preflight is not failing on a foreign or hand-edited config — it is failing on entries cbm itself wrote in v0.10.2. The upgrade path is what breaks it.
That is the same defect class as #1630, fixed for OpenCode earlier today in PR #1640: the ownership check demanded the entry match what the current version writes, exactly, so an entry written by an earlier version was classified as foreign and refused. There it was an extra "enabled" key in JSON; here it is whatever v0.10.2 wrote into TOML that v0.10.4 no longer recognises.
Two reports, two config formats, one root cause: we refuse our own previous output. That reframes this from "a Codex regression in v0.10.4" to "our recognition is version-brittle", which is a bigger and more important bug — every future format change will strand every existing user until someone hand-edits their config.
@astandrik — your #1638 gives preflight real reasons, which is exactly what is needed to confirm this: with it, the failure would say which check refused rather than leaving us to infer. Worth checking whether the reconciler treats a v0.10.2-era inline hook assignment as ambiguous.
I have asked @spam0115 whether they still have the old entries so we can diff the shapes rather than guess.
EOF
@DeusData, I checked the released v0.10.2 writer instead of assuming the old shape. It writes the managed SessionStart and SubagentStart AOT pair, not an inline assignment.
I added that v0.10.2 shape in 386dccbd, with BOM, CRLF, both Windows command forms, and adjacent user TOML. On #1638, check-only accepts it with failure=none; upsert is byte-identical and idempotent; remove deletes only the managed block. A foreign command and an extra field still return ambiguous_hook_ownership without changing the file. The focused ASan/UBSan suites pass: 312 tests.
The released v0.10.2 output therefore does not reproduce the refusal, so I did not relax the production ownership checks. To identify the remaining shape, we need either the old pre-upgrade hook section or a rerun with #1638's detailed reason= diagnostic.
Verified fixed on main (v0.10.6-to-be): #1638 (merge 3162f09) accepts the managed v0.10.2 hook shapes and names the refusal reason when content is genuinely ambiguous. End-to-end check with a byte-faithful v0.10.2-written config.toml (managed SessionStart/SubagentStart AOT pair incl. command_windows, LF): install completes with zero Codex errors, reconciles both hook commands to the current binary path, preserves sibling entries, and the Codex CLI: section header prints again. The Windows CRLF+BOM variant is covered by a dedicated regression test from that PR. A config that matches no shape any release ever wrote still refuses fail-closed — now with reason=ambiguous_hook_ownership so it is diagnosable. Thanks for the precise two-symptom report; if v0.10.6 still misbehaves on your real config, please reopen with the config's hook section.
Activity
astandrik commentedon Aug 14, 2026
I traced the missing heading to
0cf0ccb5. The new preflight runs beforeinstall_generic_agent_config(), soCodex CLI:is never printed when reconciliation refuses the config.I reproduced the refusal with an inline
hooks.SessionStartvalue that mixes a CBM-owned command with a foreign command. The reconciler correctly leaves the file byte-identical. The exact reporter config from #1560 is not public, so this is the closest reproducible ownership case rather than proof of the same input.PR #1638 restores the heading and reports a stable reason such as
reason=ambiguous_hook_ownershipwithout weakening the fail-closed behavior. It is the deeper editor-reason follow-up you described; #1629 still adds useful target metadata.DeusData commentedon Aug 14, 2026
New evidence that sharpens this considerably, from @spam0115 on #1580 (Windows, v0.10.4):
So
hook_preflightis not failing on a foreign or hand-edited config — it is failing on entries cbm itself wrote in v0.10.2. The upgrade path is what breaks it.That is the same defect class as #1630, fixed for OpenCode earlier today in PR #1640: the ownership check demanded the entry match what the current version writes, exactly, so an entry written by an earlier version was classified as foreign and refused. There it was an extra
"enabled"key in JSON; here it is whatever v0.10.2 wrote into TOML that v0.10.4 no longer recognises.Two reports, two config formats, one root cause: we refuse our own previous output. That reframes this from "a Codex regression in v0.10.4" to "our recognition is version-brittle", which is a bigger and more important bug — every future format change will strand every existing user until someone hand-edits their config.
@astandrik — your #1638 gives preflight real reasons, which is exactly what is needed to confirm this: with it, the failure would say which check refused rather than leaving us to infer. Worth checking whether the reconciler treats a v0.10.2-era inline hook assignment as ambiguous.
I have asked @spam0115 whether they still have the old entries so we can diff the shapes rather than guess.
EOF
astandrik commentedon Aug 15, 2026
@DeusData, I checked the released v0.10.2 writer instead of assuming the old shape. It writes the managed
SessionStartandSubagentStartAOT pair, not an inline assignment.I added that v0.10.2 shape in 386dccbd, with BOM, CRLF, both Windows command forms, and adjacent user TOML. On #1638, check-only accepts it with
failure=none; upsert is byte-identical and idempotent; remove deletes only the managed block. A foreign command and an extra field still returnambiguous_hook_ownershipwithout changing the file. The focused ASan/UBSan suites pass: 312 tests.The released v0.10.2 output therefore does not reproduce the refusal, so I did not relax the production ownership checks. To identify the remaining shape, we need either the old pre-upgrade hook section or a rerun with #1638's detailed
reason=diagnostic.DeusData commentedon Aug 17, 2026
Verified fixed on main (v0.10.6-to-be): #1638 (merge 3162f09) accepts the managed v0.10.2 hook shapes and names the refusal reason when content is genuinely ambiguous. End-to-end check with a byte-faithful v0.10.2-written config.toml (managed SessionStart/SubagentStart AOT pair incl. command_windows, LF):
installcompletes with zero Codex errors, reconciles both hook commands to the current binary path, preserves sibling entries, and theCodex CLI:section header prints again. The Windows CRLF+BOM variant is covered by a dedicated regression test from that PR. A config that matches no shape any release ever wrote still refuses fail-closed — now withreason=ambiguous_hook_ownershipso it is diagnosable. Thanks for the precise two-symptom report; if v0.10.6 still misbehaves on your real config, please reopen with the config's hook section.