What version of Codex are you using?
codex-cli 0.147.0
What subscription do you have?
ChatGPT paid subscription with multiple local CODEX_HOME profiles.
What model were you using?
gpt-5.6-sol (the failure is in local hook control flow and appears model-independent).
What platform are you using?
Linux 7.0.0-28-generic x86_64 unknown, reached from Windows Terminal over SSH, with Codex running in long-lived tmux sessions.
What issue are you seeing?
A long-running Codex CLI session can become trapped in an effectively infinite loop when its Stop command hook repeatedly returns a blocking result after an external runtime dependency becomes invalid.
In the observed case, the exact versioned hook launcher file was still present and executable. The failure occurred deeper in the hook: a shared configuration source had moved to a newer runtime checkout while the live session still used an older launcher generation. The hook could no longer resolve a compatible runtime candidate and returned the same blocking feedback on every invocation:
Stop hook (blocked)
feedback: Multi Server Sync Hook Router was not found; run gateway-service.py ensure or set MULTI_SERVER_SYNC_ROOT
When the assistant tried to finish after reporting the failure, Codex invoked Stop again. The hook returned the identical block, its feedback caused another model turn, and the next attempt to finish invoked the same failing hook again. The loop did not converge or return stable control to the user. Multiple long-running sessions exposed the same pattern.
This is not a missing hook executable in the current reproduction. It is a hook dependency/infrastructure failure that Codex treats like a fresh intentional policy block indefinitely. Manual process termination or session restart stops the loop, but restarting a long-running stateful session loses continuity and should not be the only escape path.
Steps to reproduce
- Configure a command
Stop hook that normally permits completion but depends on runtime or configuration state outside the Codex process.
- Start Codex CLI and keep the session running.
- Change that external dependency so the hook launcher still exists and runs, but it returns the same blocking error on every
Stop event.
- Ask Codex to complete the turn.
- Observe that the blocked-hook feedback produces another model turn.
- Observe that every subsequent attempt to finish invokes
Stop again, receives the same block, and continues without a bounded retry limit or user-visible escape.
Expected behavior
A Stop hook may intentionally block one stop attempt, but Codex must not create an unbounded automatic loop when the same hook returns the same block repeatedly without new user input or measurable progress.
At minimum, Codex should:
- detect and suppress identical consecutive
Stop blocks after a small bounded number of attempts;
- pause and return control to the user instead of automatically starting another model turn;
- distinguish hook execution/infrastructure failures from deliberate policy denials; and
- provide a safe, explicit escape path that ends the current turn while clearly reporting whether a hook was bypassed.
If a deployment chooses fail-closed behavior for hook failures, it should fail closed once and wait for user action, not consume unbounded model turns and tokens.
Additional information
Live verification confirmed that the historical versioned hook-router.py path still existed. The router failed later because its shared configuration source selected a newer runtime checkout that did not match the live launcher generation, leaving no compatible candidate root. This distinction matters: restoring a missing plugin cache path is not the applicable fix for this incident.
Related reports:
- #34477 covers an infinite loop caused by hook-injected
<hook_prompt> messages. This report reproduces the same unbounded-stop safety gap from a different trigger: repeated blocking feedback caused by an invalid external hook dependency.
- #31383 covers running sessions retaining hook commands under plugin cache directories that were deleted. Here the exact hook launcher remained present.
- #25285 concerns Windows Codex Desktop and stale hashed skill paths, not Linux CLI
Stop hook control flow.
We are intentionally omitting customer data, account identifiers, IP addresses, credentials, and private session screenshots. We can provide a sanitized diagnostic bundle or test a candidate fix.
What version of Codex are you using?
codex-cli 0.147.0What subscription do you have?
ChatGPT paid subscription with multiple local
CODEX_HOMEprofiles.What model were you using?
gpt-5.6-sol(the failure is in local hook control flow and appears model-independent).What platform are you using?
Linux 7.0.0-28-generic x86_64 unknown, reached from Windows Terminal over SSH, with Codex running in long-lived tmux sessions.What issue are you seeing?
A long-running Codex CLI session can become trapped in an effectively infinite loop when its
Stopcommand hook repeatedly returns a blocking result after an external runtime dependency becomes invalid.In the observed case, the exact versioned hook launcher file was still present and executable. The failure occurred deeper in the hook: a shared configuration source had moved to a newer runtime checkout while the live session still used an older launcher generation. The hook could no longer resolve a compatible runtime candidate and returned the same blocking feedback on every invocation:
When the assistant tried to finish after reporting the failure, Codex invoked
Stopagain. The hook returned the identical block, its feedback caused another model turn, and the next attempt to finish invoked the same failing hook again. The loop did not converge or return stable control to the user. Multiple long-running sessions exposed the same pattern.This is not a missing hook executable in the current reproduction. It is a hook dependency/infrastructure failure that Codex treats like a fresh intentional policy block indefinitely. Manual process termination or session restart stops the loop, but restarting a long-running stateful session loses continuity and should not be the only escape path.
Steps to reproduce
Stophook that normally permits completion but depends on runtime or configuration state outside the Codex process.Stopevent.Stopagain, receives the same block, and continues without a bounded retry limit or user-visible escape.Expected behavior
A
Stophook may intentionally block one stop attempt, but Codex must not create an unbounded automatic loop when the same hook returns the same block repeatedly without new user input or measurable progress.At minimum, Codex should:
Stopblocks after a small bounded number of attempts;If a deployment chooses fail-closed behavior for hook failures, it should fail closed once and wait for user action, not consume unbounded model turns and tokens.
Additional information
Live verification confirmed that the historical versioned
hook-router.pypath still existed. The router failed later because its shared configuration source selected a newer runtime checkout that did not match the live launcher generation, leaving no compatible candidate root. This distinction matters: restoring a missing plugin cache path is not the applicable fix for this incident.Related reports:
<hook_prompt>messages. This report reproduces the same unbounded-stop safety gap from a different trigger: repeated blocking feedback caused by an invalid external hook dependency.Stophook control flow.We are intentionally omitting customer data, account identifiers, IP addresses, credentials, and private session screenshots. We can provide a sanitized diagnostic bundle or test a candidate fix.