{"record":{"id":"92667d8240336676","repo":"HKUDS/Vibe-Trading","slug":"binance-usd-m-assets-must-include-usdt","errorCode":null,"errorMessage":"Binance USD-M assets must include USDT","messagePattern":"Binance USD-M assets must include USDT","errorType":"exception","errorClass":"UsdMObservationError","httpStatus":null,"severity":"critical","filePath":"agent/src/trading/connectors/binance/usdm.py","lineNumber":253,"sourceCode":"        \"marginBalance\",\n        \"availableBalance\",\n        \"initialMargin\",\n        \"positionInitialMargin\",\n        \"openOrderInitialMargin\",\n        \"maintMargin\",\n        \"unrealizedProfit\",\n    )\n    for asset in assets:\n        symbol = str(asset.get(\"asset\") or \"\").upper()\n        balances = tuple(_number(asset.get(field), field) for field in balance_fields)\n        if symbol == \"USDT\":\n            if usdt_asset is not None:\n                raise UsdMObservationError(\"Binance USD-M assets must include exactly one USDT row\")\n            usdt_asset = asset\n        elif any(value != 0 for value in balances):\n            raise UsdMObservationError(\"Binance USD-M Shadow Account supports the USDT asset only\")\n    if usdt_asset is None:\n        raise UsdMObservationError(\"Binance USD-M assets must include USDT\")\n    return usdt_asset\n\n\ndef _require_coherent_totals(\n    account: Mapping[str, float],\n    positions: list[dict[str, Any]],\n    close_enough: CloseEnough,\n) -> None:\n    comparisons = (\n        (\n            account[\"total_unrealized_pnl\"],\n            sum(row[\"unrealized_pnl\"] for row in positions),\n        ),\n        (\n            account[\"total_initial_margin\"],\n            sum(row[\"initial_margin\"] for row in positions),\n        ),\n        (","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/binance/usdm.py#L235-L271","documentation":"Raised by _require_usdt_assets when the parsed Binance USD-M account assets contain no USDT row (usdt_asset is None after scanning all asset balances). The Shadow Account model only supports USDT as margin asset, so the account snapshot is rejected as unusable. It is an internal consistency check on exchange account data, not on user input.","triggerScenarios":"Calling read_account_observation (via _account_values) with an account payload whose balances list has no asset=='USDT' entry, e.g. an account holding only BNB/USDC margin, or a stubbed/mocked REST response missing the USDT balance row.","commonSituations":"Test fixtures or mocks that omit the USDT asset; multi-currency margin enabled on the Binance futures account; switching the exchange account to a USDⓈ-M account funded with a non-USDT asset; upstream schema changes renaming the asset field.","solutions":["Inspect the raw v2/account or balance payload and confirm an asset row with asset == 'USDT' exists","If the account uses multi-assets margin or non-USDT collateral, disable it in Binance futures settings so the account is USDT-margined","Fix test/mock data to include a USDT balance row","Verify the connector is pointed at a USDⓈ-M (futures) account, not spot or COIN-M"],"exampleFix":"// before\nbalances = [{\"asset\": \"USDC\", \"balance\": \"100.0\"}]\n// after\nbalances = [{\"asset\": \"USDT\", \"balance\": \"100.0\"}, {\"asset\": \"USDC\", \"balance\": \"0.0\"}]","handlingStrategy":"validation","validationCode":"def has_usdt_balance(payload: dict) -> bool:\n    return any(\n        str(row.get(\"asset\", \"\")).upper() == \"USDT\" for row in payload.get(\"balances\", [])\n    )\n\nif not has_usdt_balance(account_payload):\n    raise ValueError(\"account has no USDT margin asset\")","typeGuard":null,"tryCatchPattern":"try:\n    obs = connector.read_account_observation(...)\nexcept UsdMObservationError as exc:\n    if \"must include USDT\" in str(exc):\n        logger.error(\"account not USDT-margined: %s\", exc)\n        halt_trading()\n    raise","preventionTips":["Keep the futures account in single-asset USDT margin mode","Validate balances contain a USDT row before starting the trading loop","Include a USDT row in every account fixture"],"tags":["binance","usdm","futures","account-validation","usdt"],"backgroundTag":"exchange-account-data-validation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}