Skip to content

[Bug] binance_sdk_derivatives_trading_usds_futures: UserDataStreamEventsResponse.from_dict raises "Multiple matches found" due to ambiguous schemas #475

@ZerolBozi

Description

@ZerolBozi

I am using the binance_sdk_derivatives_trading_usds_futures package. When consuming the User Data Stream, the SDK's websocket client returns a raw dict for UserDataStreamEventsResponse (as intended for oneOf types). However, when attempting to convert this dictionary into a Pydantic model using UserDataStreamEventsResponse.from_dict(), the operation fails with a ValueError: Multiple matches found.

Steps to Reproduce

  1. Subscribe to the User Data Stream via DerivativesTradingUsdsFuturesWebSocketStreams.
  2. Receive a standard event payload (e.g., ORDER_TRADE_UPDATE) in the callback.
  3. Note: The callback receives a dict because the SDK skips auto-deserialization for oneOf models in websocket.py.
  4. Attempt to deserialize the payload manually:
import asyncio

from binance_sdk_derivatives_trading_usds_futures.derivatives_trading_usds_futures import DerivativesTradingUsdsFutures
from binance_sdk_derivatives_trading_usds_futures.websocket_streams.models.user_data_stream_events_response import UserDataStreamEventsResponse

client = DerivativesTradingUsdsFutures(...)
async def start_stream():
    try:
        connection = client.websocket_streams.create_connection()

        user_stream = connection.user_data(listen_key)
        user_stream.on("message", _on_ws_user_data_message)

    except Exception as e:
        logging.error(f"start_stream() error: {e}")
    finally:
        if connection:
            await connection.close_connection(close_session=True)

def _on_ws_user_data_message(message: dict):
    response = UserDataStreamEventsResponse.from_dict(message)
    """
    # Error Msg
    File "D:\test_project\.venv\lib\site-packages\binance_sdk_derivatives_trading_usds_futures\websocket_streams\models\user_data_stream_events_response.py", line 300, in from_json
    raise ValueError(
    ValueError: Multiple matches found when deserializing the JSON string into UserDataStreamEventsResponse with oneOf schemas: AccountConfigUpdate, AccountUpdate, AlgoUpdate, ConditionalOrderTriggerReject, GridUpdate, Listenkeyexpired, MarginCall, OrderTradeUpdate, StrategyUpdate, TradeLite. Details: 1 validation error for Listenkeyexpired
    E
    Input should be a valid string [type=string_type, input_value=1766981401938, input_type=int]
    """

if __name__ == "__main__":
    asyncio.run(start_stream())
  1. The code raises a ValueError

Observed Error
ValueError: Multiple matches found when deserializing the JSON string into UserDataStreamEventsResponse with oneOf schemas: AccountConfigUpdate, AccountUpdate, AlgoUpdate...

Root Cause Analysis The issue lies in the generated from_json / from_dict logic within UserDataStreamEventsResponse combined with overly permissive schema definitions in this specific SDK (binance_sdk_derivatives_trading_usds_futures).

  1. Brute-Force Matching: The from_json method iterates through all oneOf candidate models, attempting to validate the input against each one.

  2. Ambiguous Schemas (The "Wildcard" Problem): Several generated models in this package, such as AccountConfigUpdate and StrategyUpdate, define all their fields as Optional and include additional_properties.

Impact Users cannot strictly type-check or deserialize User Data Stream events using the provided SDK models. We are forced to implement manual discriminators (checking payload['e']) to bypass the SDK's broken deserialization logic.

Suggested Fix The UserDataStreamEventsResponse deserialization logic should use a discriminator (the e field in the JSON payload) to determine the correct target model, rather than relying on a brute-force trial that is prone to ambiguity.

Environment

  • Package: binance_sdk_derivatives_trading_usds_futures=5.0.0
  • Python Version: 3.10.11

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions