Summary
The Listen v2 AsyncV2SocketClient.__aiter__ (deepgram/listen/v2/socket_client.py:35-46) uses construct_type(type_=V2SocketClientResponse, object_=...) to decode incoming messages. V2SocketClientResponse is a Union[ListenV2Connected, ListenV2TurnInfo, ListenV2ConfigureSuccess, ListenV2ConfigureFailure, ListenV2FatalError] — it does not include a Warning member.
For messages whose type field is not in the union (e.g. Flux's Warning with code FORCE_END_TURN_NO_ACTIVE_TURN), construct_type returns None rather than raising. The iterator's surrounding except Exception guard therefore does not fire, and the bare None is silently yielded to consumers.
Reproduction
import json
from deepgram.core.unchecked_base_model import construct_type
from deepgram.listen.v2.socket_client import V2SocketClientResponse
payload = {
"type": "Warning",
"request_id": "test",
"sequence_id": 1,
"code": "FORCE_END_TURN_NO_ACTIVE_TURN",
"description": "no active turn",
}
result = construct_type(type_=V2SocketClientResponse, object_=payload)
print(result) # None
Verified against deepgram-sdk==7.8.1 on Python 3.11.
Impact
Client code that pattern-matches on the SDK's typed union (e.g. isinstance(msg, ListenV2TurnInfo)) cannot see Warning messages at all — they show up as bare None yields, indistinguishable from any other unknown-type payload.
Per the Flux docs, sending ForceEndTurn before Flux has emitted StartOfTurn (e.g. a silent push-to-talk turn) results in a Warning FORCE_END_TURN_NO_ACTIVE_TURN — the documented correct handling is "no active turn, treat as empty completion." Consumers using the SDK's public typed iterator can't reliably detect this case and instead end up waiting for an EndOfTurn that never arrives.
Suggested fixes (any one)
- Add a
ListenV2Warning type (type: Literal["Warning"], code: str, description: str) and include it in V2SocketClientResponse.
- Change
AsyncV2SocketClient.__aiter__ to yield the raw dict (with a debug log) when the typed decode returns None, so consumers can still see it.
- At minimum, log the raw payload at INFO/WARNING when
construct_type returns None, so the drop is observable in dev.
Workaround currently in use
Iterating socket._websocket directly and parsing raw JSON in the consumer. This works but couples client code to a private SDK attribute.
Summary
The Listen v2
AsyncV2SocketClient.__aiter__(deepgram/listen/v2/socket_client.py:35-46) usesconstruct_type(type_=V2SocketClientResponse, object_=...)to decode incoming messages.V2SocketClientResponseis aUnion[ListenV2Connected, ListenV2TurnInfo, ListenV2ConfigureSuccess, ListenV2ConfigureFailure, ListenV2FatalError]— it does not include aWarningmember.For messages whose
typefield is not in the union (e.g. Flux'sWarningwith codeFORCE_END_TURN_NO_ACTIVE_TURN),construct_typereturnsNonerather than raising. The iterator's surroundingexcept Exceptionguard therefore does not fire, and the bareNoneis silently yielded to consumers.Reproduction
Verified against
deepgram-sdk==7.8.1on Python 3.11.Impact
Client code that pattern-matches on the SDK's typed union (e.g.
isinstance(msg, ListenV2TurnInfo)) cannot seeWarningmessages at all — they show up as bareNoneyields, indistinguishable from any other unknown-type payload.Per the Flux docs, sending
ForceEndTurnbefore Flux has emittedStartOfTurn(e.g. a silent push-to-talk turn) results in aWarning FORCE_END_TURN_NO_ACTIVE_TURN— the documented correct handling is "no active turn, treat as empty completion." Consumers using the SDK's public typed iterator can't reliably detect this case and instead end up waiting for anEndOfTurnthat never arrives.Suggested fixes (any one)
ListenV2Warningtype (type: Literal["Warning"],code: str,description: str) and include it inV2SocketClientResponse.AsyncV2SocketClient.__aiter__to yield the raw dict (with a debug log) when the typed decode returnsNone, so consumers can still see it.construct_typereturnsNone, so the drop is observable in dev.Workaround currently in use
Iterating
socket._websocketdirectly and parsing raw JSON in the consumer. This works but couples client code to a private SDK attribute.