Repository navigation
CLI /review follow-up fails with review_rollout_user id: Expected an ID that begins with 'msg' #27928
Description
What version of Codex CLI is running?
codex-cli 0.139.0
What subscription do you have?
Using an Azure OpenAI / Azure Foundry model provider.
Which model were you using?
gpt-5.5-1
What platform is your computer?
Darwin arm64 macOS 26.5.1
What terminal emulator and version are you using (if applicable)?
Ghostty 1.3.1, zsh
Codex doctor report
Not pasting the full report because it contains local paths and provider-specific resource names.
Relevant redacted excerpts:
{
"overallStatus": "ok",
"codexVersion": "0.139.0",
"config.load": {
"model provider": "azure",
"model": "gpt-5.5-1"
},
"network.websocket_reachability": {
"model provider": "azure",
"provider name": "Azure OpenAI",
"wire API": "responses",
"supports websockets": "false"
},
"updates.status": {
"latest version": "0.139.0",
"version status": "current version is not older"
}
}What issue are you seeing?
Running /review can leave the session in a state where the next Codex request fails with a Responses API validation error:
{
"error": {
"message": "Invalid 'input[0].id': 'review_rollout_user'. Expected an ID that begins with 'msg'.",
"type": "invalid_request_error",
"param": "input[0].id",
"code": "invalid_value"
}
}This appears related to the older /review issues that were closed after fixing the colon-containing id (review:rollout:user) in #9360 / #9131, and to #9860 which reported the same review_rollout_user / Expected an ID that begins with 'msg' error. The current failure is still reproducible on the latest published CLI version, 0.139.0.
From inspecting the current source, /review still materializes local message ids named review_rollout_user / review_rollout_assistant, and attach_item_ids later reattaches stored item ids into serialized Responses API message items. That means a local client-generated message id can be sent back as input[].id, while the API expects message ids to be server-generated ids beginning with msg.
A similar root cause is described in the still-open hook issue #20783, where a local UUID message id is sent back to the Responses API and rejected with the same Expected an ID that begins with 'msg' validation rule.
What steps can reproduce the bug?
- Configure Codex CLI 0.139.0 with an Azure OpenAI / Azure Foundry provider using the
responseswire API. - Open a repository.
- Run
/review. - After the review finishes, continue in the same session with a follow-up prompt.
- The next request can fail immediately with the validation error above.
What is the expected behavior?
The /review command should be able to roll its result back into the parent session and allow follow-up prompts without sending local client-generated message ids as Responses API input[].id values.
Additional information
The previous fix in #9387 appears to have addressed the older Azure validation failure caused by colons in review:rollout:user, but the current validation rule rejects review_rollout_user because message item ids are expected to begin with msg.
A minimal fix might be to preserve id for non-message Responses API output item types, but only reattach message.id when it looks like a server-generated message id, for example when it starts with msg. Locally generated message ids such as review_rollout_user, review_rollout_assistant, and UUIDs should not be serialized as Responses API message ids.
Activity
He-wei-gui commentedon Jun 27, 2026
I reproduced the
/reviewfollow-up path in source and prepared a minimal patch locally.Root cause:
/reviewrecords parent-session rollout messages with local IDs such asreview_rollout_userandreview_rollout_assistant.store: true.storeis true, so those local message IDs can be serialized asinput[].id.msg, so it rejectsreview_rollout_user.Patch shape:
ResponseItem::Message.idwhen it does not start withmsg.msg...intact.review_history_surfaces_in_parent_sessionso it runs through the Azure/store path and asserts the review rollout messages are present but have no serializedid.Local validation:
cargo fmt -- --config imports_granularity=Item --checkpassed, with stable-rustfmt warnings thatimports_granularity=Itemis nightly-only.git diff --checkpassed.cargo check -p codex-core --libpassed.just test -p codex-core review_history_surfaces_in_parent_sessioncould not complete locally: the first run failed during initial Windows dependency build atcrossbeam-utilswithout a useful diagnostic, and the second single-job run exceeded a 15 minute timeout during first workspace build.If maintainers want an invited PR, I have a branch ready:
pavlentij commentedon Jul 14, 2026
The same on the latest ChatGPT Desktop for Mac (Version 26.707.71524). The thread couldn't be used anymore, as the error comes with every single message:
The issue occurred after the code review started, and then a message was sent from the iOS app to the thread.
Reported with the feedback (019f56e9-9a75-7ed0-8c18-9b99ac2ce57b).
rkoivunen-sw commentedon Jul 14, 2026
26.707.71524 Win11 desktop. Seeing same issue as pvalentij.
Manually editing all sessions fixed the issue for a few rounds of chats, but then got new corrupted messages: a hook feedback item gets a UUIDv7 id → invalid_id_prefix at input[0].
Extra details from digging through my rollout files:
Update — root cause narrowed down: the corruption comes from the stop-hook follow-up prompt injection path. I classified every bad id in my session history (48 distinct UUIDv7s): all 48 are hook-injected messages (
<hook_prompt hook_run_id="stop:...">...), zero are normal typed messages. The injected item is persisted with the app's internal UUIDv7 as itsid; normal user messages are stored with noidat all.It's a fresh regression, not a config issue: my hook script is unchanged since June 1 and ran fine for 5+ weeks, and every bad id is minted after 2026-07-09 19:00 UTC (UUIDv7 timestamps) — matching the early-July builds that reworked hook context/trust handling. Microsoft Store install, auto-updated, so the regression shipped in whatever build rolled out around July 8–9.
Workaround confirmed: disabling the prompt-injecting stop hook stops new corruption entirely (plus the recursive id scrub above for already-poisoned threads).
sagi6s commentedon Jul 16, 2026
This is not Azure-specific, and it reproduces on OpenAI's own first-party subscriptions — including the latest 0.144.5.
The "please report this to Azure" response on the earlier issues (#9360) does not hold up. In this very thread, @pavlentij reproduced the exact same
review_rollout_userid on ChatGPT Desktop for Mac (26.707.71524) — a first-party client, no Azure involved. #33176 shows the sameExpected an ID that begins with 'msg'on a PRO 20x subscription. So this is not a "temporary bug in Azure's endpoint" — it is a client-side bug in how Codex serializes locally-generated message ids back into the Responses API.The root cause has been stated plainly and repeatedly:
/review(and the hook-injection path) mint local message ids likereview_rollout_user/ UUIDv7, andattach_item_idssends them back asinput[].id, which the Responses API rejects because message ids must be server-generated (msg…). The:→_normalization in #9387 only swapped one validation failure for another.This has now been open and reproducible across 0.114 → 0.144.5 (the current latest) and multiple first-party app builds, with a proposed patch shape already posted (clear
ResponseItem::Message.idwhen it does not start withmsg). Deflecting first-party reproductions to "go tell Azure" is not an acceptable resolution. Please pick up the fix.HenryXiaoYang commentedon Jul 22, 2026
When this issue will be fixed? Its been really irritating
quantranhong1999 commentedon Jul 24, 2026
Having the same issue with Codex MacOs here. The terminal is ok for me though.
GuyPaddock commentedon Jul 29, 2026
I can reproduce this on
codex-cli 0.146.0, so the issue remains present in a newer release than the originally reported0.139.0.After using
/reviewseveral times in a long-running session, every subsequent prompt fails with:Changing the model and reasoning effort does not help. Remote compaction also fails with the same validation error:
Inspection of the local rollout JSONL confirms that it contains persisted message items using both synthetic IDs:
review_rollout_userreview_rollout_assistantNormal message items in the same rollout use server-style
msg_...IDs. This supports the root-cause analysis in the issue: review messages are persisted with client-generated IDs, andattach_item_idslater serializes those IDs into Responses APIinput[].id.Because the invalid IDs are persisted, restarting Codex or switching models does not recover the session. Compaction cannot recover it either because compaction replays the same malformed item.
Expected behavior: Codex should only attach message IDs that are valid server-generated IDs, such as IDs beginning with
msg, and should omit locally generated review IDs when serializing Responses API input. Existing rollouts containing these synthetic IDs should ideally be sanitized during replay so affected sessions can be recovered.Reidddddd commentedon Jul 29, 2026
Bump into the same issue,
codex-cli 0.146.0, MacOSHe-wei-gui commentedon Jul 29, 2026
Thanks for the additional confirmations. The reports from
codex-cli 0.146.0and ChatGPT Desktop on both macOS and Windows show that this is not Azure-specific and is still present in current first-party clients.I prepared an earlier minimal patch in [dbca2ed](He-wei-gui@dbca2ed). During Responses request preparation, it removes
ResponseItem::Message.idvalues that do not start withmsg, while preserving valid server-generated message IDs and IDs belonging to non-message response items.The later reports about hook-injected UUIDv7 message IDs appear to confirm that the same validation should cover both
/reviewrollout messages and hook follow-up messages. Applying the guard during request preparation should also prevent already-persisted invalid message IDs from being replayed to the API, allowing affected sessions to work again without manually editing rollout files.Maintainers, if this direction is acceptable, I can rebase the branch onto the current
mainbranch and prepare an invited PR with regression coverage for:/reviewsynthetic message IDsWould you like me to proceed with an invited PR?
walid-baharwal commentedon Jul 29, 2026
Confirmed on Linux with OpenAI first-party authentication:
After upgrading to 0.146.0, resuming an existing long-running session containing /review results caused every subsequent prompt to fail with:
The session JSONL remained intact. I found 12 local sessions containing the review_rollout_user message ID. The failure persisted across retries because the invalid ID was replayed from saved and compacted history.
This confirms the issue is also reproducible on Ubuntu/Linux and is not platform-specific. I downgraded to 0.145.0 as a temporary workaround.
warproxxx commentedon Jul 30, 2026
I reproduced this on
codex-cli 0.146.0by resuming a legacy0.144.6rollout whose compactedreplacement_historycontains message items with:review_rollout_userreview_rollout_assistantThe exact failure is:
Root cause: #32312 added request-time filtering for unprefixed legacy response item IDs, but
ResponseItemId::is_prefixed()currently accepts any non-empty text on both sides of the first underscore. Thereforereview_rollout_useris considered “prefixed” even though aResponseItem::Messagespecifically requires themsgprefix. The incompatible ID survives request preparation and is replayed to the Responses API.I prepared a focused fix against current
main:ResponseItem::id_prefix()mapping.Branch: https://github.com/warproxxx/codex/tree/fix/legacy-review-message-id-prefix
Commit: warproxxx@7ed1e6a
Validation:
review_rollout_*IDs present in outbound JSON.just test -p codex-protocol: 268 passed.just test -p codex-core: 3,184 passed; the two remaining failures are unrelated macOS sandbox/path cases (apply_patch_cli_does_not_write_through_symlink_escape_outside_workspaceandopenpty_works_under_real_exec_seatbelt_path).just fix -p codex-protocol,just fix -p codex-core, andjust fmtcompleted.This also covers the Codex App report in #34283. Per the repository's invitation-only contribution policy, I have not opened an unsolicited PR. If a maintainer confirms this approach and explicitly invites the contribution, I can open the ready branch immediately.
Reidddddd commentedon Aug 24, 2026
still buggy in 0.149.1..
have to downgraded back to 0.145.0....