0.117.0 regression: UserPromptSubmit hook output is not rendered in TUI/app-server path

Resolved 💬 3 comments Opened Mar 27, 2026 by 92645417d9e5c763259dbebc306e3e Closed Mar 27, 2026
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

0.117.0

What subscription do you have?

Plus

Which model were you using?

_No response_

What platform is your computer?

_No response_

What terminal emulator and version are you using (if applicable)?

_No response_

What issue are you seeing?

In Codex CLI 0.117.0, UserPromptSubmit hook output is not rendered in the TUI when running through the app-server path.

This is visible in at least two cases:

  1. Cold start in default mode, where the first prompt is blocked by a UserPromptSubmit hook.
  2. Resuming an old conversation in default mode and then sending input.

Expected hook UI such as:

  • Running UserPromptSubmit hook: checking go-workflow input policy
  • UserPromptSubmit hook (stopped)
  • warning: go-workflow must start from PlanMode...

does not appear at all. Instead, the UI immediately returns to a new input box with no visible hook message.

On 0.116, the same setup does show the hook output correctly.

I locally patched 0.117.0 from source and confirmed the regression appears to have two parts:

  • app-server HookStarted / HookCompleted notifications are dropped during conversion before rendering
  • in the no-primary-thread cold-start path, hook notifications can also be buffered and never shown

So this does not appear to be only a “first prompt” issue.

What steps can reproduce the bug?

  1. Configure a UserPromptSubmit hook that blocks input and emits visible stop/warning text.
  2. Start Codex CLI 0.117.0 in default mode.
  3. Submit a prompt that triggers the hook, for example $go-workflow.
  4. Observe that no hook text is rendered and the UI immediately shows another input prompt.

Also reproducible when:

  1. Resume an existing conversation in default mode.
  2. Submit input that triggers the same UserPromptSubmit hook.
  3. Observe that no hook output is shown.

What is the expected behavior?

The TUI should render the hook status and stop output, similar to 0.116, for example:

  • Running UserPromptSubmit hook: ...
  • UserPromptSubmit hook (stopped)
  • the emitted warning/stop lines

Additional information

Regression observed between 0.116 and 0.117.0.

If useful, I have a local source patch against rust-v0.117.0 that restores visibility by:

  • explicitly converting app-server hook notification payloads instead of relying on JSON shape conversion
  • rendering hook notifications immediately when no primary thread/session exists yet

userpromptsubmit-hook-visibility-fix.patch

View original on GitHub ↗

3 Comments

IVIarvin · 5 months ago

I have the same behaviour. With /mycustomprompt in a 0.116 terminal, I can use the autocomplete. In 0.117, when I do /mycustomprompt I don't see it. No environnement change, just the update

Boulea7 · 5 months ago

I took a quick pass through the app-server -> TUI path, and this looks like it may be two problems rather than one.

First, the hook notification bridge looks fragile.

app-server-protocol hook notifications are coming from the v2 layer, while the core codex_protocol hook event types still use different serde naming. In tui_app_server, ServerNotification::HookStarted / HookCompleted currently go through convert_via_json(notification.run) before being turned back into core hook events.

That matches the symptom here pretty well: if that conversion fails, the hook notification is just skipped and nothing gets rendered.

Second, the cold-start buffering path also looks suspicious.

ThreadEventStore::event_survives_session_refresh(...) currently only retains buffered Request(_) events across refresh. So even if the bridge conversion were fixed, an early hook notification still looks like it could get dropped before the session is fully established.

What I did not find was a test that starts from app-server HookStartedNotification / HookCompletedNotification and verifies that the hook UI survives the notification conversion path. The existing hook rendering tests I found appear to inject core EventMsg::HookStarted / HookCompleted directly.

So from source inspection, this looks consistent with the regression report:

  • notification bridge may be dropping hook events
  • early hook notifications may also be lost during session refresh

I have not reproduced this end-to-end locally, so this is based on code inspection only, but I think the strongest regression coverage here would be one app-server notification bridge test and one cold-start buffering test.

etraut-openai contributor · 5 months ago

Thanks for the bug report. This will be addressed in the next release.