Environment
- Surface: API, direct WebSocket connection from Python on macOS.
- Endpoint:
wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1 - Model:
gpt-realtime-2.1 - Input transcription model:
gpt-transcribe - Client library:
websocket-client1.9.2; Python 3.14.7. - Audio: Mono PCM16, 24 kHz.
- Turn detection:
server_vad, threshold0.7, silence duration500ms. - Noise reduction:
far_field.
Bug
During shutdown, the server committed user audio as item A, but emitted conversation.item.input_audio_transcription.completed with item B.
Retrieving both items on the same connection showed:
- A existed and contained the same final transcript received in B’s transcription event.
- B did not exist, according to the server’s retrieval error.
- A also contained four seconds of audio, matching the duration of the uploaded excerpt.
The IDs were:
A: item_ENekpCNlm80W0ngS6jyJx
B: item_ENektOWilcj4Deo8TJ5NY
Expected: The transcription completion should identify the committed user audio item. OpenAI’s transcription guide instructs clients to match transcription events to committed items using item_id.
This mismatch prevents our client from resolving A’s pending transcription. It eventually reaches its shutdown timeout and displays an unavailable-transcript placeholder followed by the transcript associated with B.
Cancellation or its timing may be involved, but the cause is not confirmed.
Reproduction
- Open a WebSocket session with the configuration above and wait for the initial
session.updated. - Stream a four-second speech excerpt in 100 ms chunks at real-time speed.
- Stop uploading while the utterance is unfinished. The server has emitted
input_audio_buffer.speech_started, but nospeech_stopped. - Send these three separate events consecutively, without waiting for acknowledgements between them:
{"type":"session.update","session":{"type":"realtime","audio":{"input":{"turn_detection":null}}}}
{"type":"response.cancel"}
{"type":"input_audio_buffer.commit","event_id":"final_input_commit"}
- Keep the connection open and process incoming events for up to ten seconds.
- Upon receiving transcription completion, retrieve both the committed item ID and the transcription event’s item ID:
{"type":"conversation.item.retrieve","item_id":"item_ENekpCNlm80W0ngS6jyJx","event_id":"retrieve_committed_item"}
{"type":"conversation.item.retrieve","item_id":"item_ENektOWilcj4Deo8TJ5NY","event_id":"retrieve_transcribed_item"}
Observed timeline — seconds relative to replay start; summarized from received events:
| Time | Event |
|---|---|
| 5.329 | session.updated confirms turn_detection: null |
| 5.330 | Cancellation returns response_cancel_not_active |
| 5.330 | input_audio_buffer.committed, conversation.item.added, and conversation.item.done identify A |
| 5.753 | conversation.item.input_audio_transcription.completed identifies B |
| 6.321 | Retrieval of A returns the same final transcript and four seconds of audio |
| 6.323 | Retrieval of B fails because B does not exist |
Control tests using the same audio excerpt:
- Omitting only
response.cancel, while retaining the session update and final commit, produced matching item IDs. This was one successful control run. - Omitting only the final commit produced no conversation item or transcription during the ten-second observation window.
Diagnostics
- Server event IDs for investigation:
Commit acknowledgement: event_ENekt2uYc48KZ031NycEZ
Transcription completion: event_ENeku2ruuiqKJq39ebvaa
Successful retrieval A: event_ENekuYhv69bCIGd6Gh1Ma
Failed retrieval B: event_ENekusbFjZymJqa0KPxWB
- When: September 13, 2026, Asia/Tokyo (UTC+09:00).
- Frequency: Reproduced in multiple replay tests containing cancellation. An occurrence rate has not been established.
- Logging: Incoming IDs were logged directly from parsed WebSocket messages before application transcript processing. The failing replay log is summarized and omits transcription deltas, so it does not establish B’s first appearance on the connection.
The response.cancel documentation says cancelling when no response is active is safe and leaves the session unaffected. Could you investigate why the transcription event references an item that cannot be retrieved, and whether cancellation immediately before committing active speech can trigger this inconsistency?