Codex Desktop: macOS Chinese IME Caps Lock switch followed by Enter can duplicate composer submission
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop 26.506.31421 (2620)
CLI/session metadata observed locally: 0.130.0-alpha.5
What subscription do you have?
Pro
What platform is your computer?
Darwin 24.5.0 arm64 arm
What issue are you seeing?
When using the built-in macOS Chinese input method, switching from Chinese input back to English/A with Caps Lock immediately before pressing Enter can intermittently cause Codex Desktop to submit the same composer message more than once.
This is not the usual IME issue where Enter is pressed while a Chinese candidate/composition is still active. In this case:
- The Chinese text has already been committed to the composer.
- I press Caps Lock to switch back to English/A.
- I press Enter shortly afterward to submit.
Observed failures include:
- the same message being appended twice in an existing thread,
- the duplicate appearing after a delay, after the assistant has already responded to the first copy,
- or a new chat creating multiple sessions with the same first user message.
The issue is timing-sensitive and hard to reproduce deterministically. It does not always require an extremely fast Enter after Caps Lock; it appears to depend on the input-source transition / app event-loop state.
I checked existing issues first. This seems adjacent to, but distinct from:
- #20767:
Escfrom active CJK IME composition passes through and interrupts the model. - #15863: Korean input mode prevents a keyboard shortcut from working.
What steps can reproduce the bug?
- On macOS, enable the built-in Chinese input method.
- Configure/use Caps Lock to switch between Chinese input and English/A.
- Open Codex Desktop.
- Focus the composer in either a new chat or an existing thread.
- Switch to Chinese input.
- Type a Chinese message and ensure the text is committed/visible in the composer.
- Press Caps Lock to switch back to English/A.
- Press Enter shortly afterward to submit.
- Repeat with short Chinese messages.
Expected intermittent result:
- Usually the message submits once.
- Sometimes the same submit is consumed more than once.
- In one live capture, the duplicate appeared about 19 seconds after the original submit and after the assistant had already responded once.
I also inspected local Codex session data after reproducing. PII/path/thread IDs/message bodies redacted:
Same-thread delayed duplicate captured live
The same user message was appended twice in the same thread:
- First user append:
2026-05-13 10:04:07.675 - Assistant response to first copy:
2026-05-13 10:04:26.407 - Delayed duplicate user append:
2026-05-13 10:04:26.948 - Assistant response to duplicate:
2026-05-13 10:04:41.551
The duplicated message body length was 265 characters. The second copy was not just a duplicate log line at the same timestamp; it was processed as a real later turn.
Duplicate new-session starts observed in local history
The local database also contains several cases where the same first user message appears in two sessions with the same working directory. These examples are redacted to only timing and message length:
| Case | Date/time | Prompt length | Evidence |
| --- | --- | ---: | --- |
| A | 2026-03-09 18:24:14 | 18 | Session A prompt at 18:24:14.098; Session B created at 18:24:14.485 (+387 ms); same prompt in Session B at 18:24:16.914 (+2.816 s). Both sessions executed. |
| B | 2026-03-26 17:17:49 | 65 | Session A prompt at 17:17:49.362; Session B created near-simultaneously; same prompt in Session B at 17:17:50.984 (+1.622 s). |
| C | 2026-04-01 17:13:48 | 56 | Session A prompt at 17:13:48.455; Session B created near-simultaneously; same prompt in Session B at 17:13:52.867 (+4.412 s). |
| D | 2026-04-09 15:30:28 | 74 | Session A prompt at 15:30:28.968; Session B created at 15:30:29.062 (+94 ms); same prompt in Session B at 15:30:30.963 (+1.995 s). Both sessions executed. |
What is the expected behavior?
One physical/user-intended Enter submit should create exactly one submit intent.
- In an existing thread, one user message should be appended.
- In a new chat, one session/thread should be created.
- Delayed async work should not replay the same draft/submission after the assistant has already responded.
Additional information
This appears related to the composer submit path consuming more than one submit intent during or shortly after a macOS input-source transition.
From inspecting the installed app bundle, the composer Enter handling appears to be in a ProseMirror/keymap-style path. Nearby keyboard handlers guard against IME composition with checks like:
event.nativeEvent.isComposing || event.keyCode === 229
The main composer Enter submit path does not appear to have an equivalent guard. However, this specific issue may not be fixed by isComposing alone, because the text is already committed. The risky window seems to be shortly after compositionend / input-source switching, especially via Caps Lock.
Suggested fix direction:
- Add an IME transition guard to the Enter submit path, including
isComposing,keyCode === 229, and possibly a short grace window aftercompositionend. - Add a synchronous single-flight/idempotency guard before async submit work starts.
- For new-chat creation, consider generating a submit-intent ID and coalescing/rejecting duplicate submissions with the same intent ID.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗