HKUDS/Vibe-Trading · critical · UsdMObservationError
Binance USD-M assets must include USDT
Error message
Binance USD-M assets must include USDT
What it means
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.
Source
Thrown at agent/src/trading/connectors/binance/usdm.py:253
"marginBalance",
"availableBalance",
"initialMargin",
"positionInitialMargin",
"openOrderInitialMargin",
"maintMargin",
"unrealizedProfit",
)
for asset in assets:
symbol = str(asset.get("asset") or "").upper()
balances = tuple(_number(asset.get(field), field) for field in balance_fields)
if symbol == "USDT":
if usdt_asset is not None:
raise UsdMObservationError("Binance USD-M assets must include exactly one USDT row")
usdt_asset = asset
elif any(value != 0 for value in balances):
raise UsdMObservationError("Binance USD-M Shadow Account supports the USDT asset only")
if usdt_asset is None:
raise UsdMObservationError("Binance USD-M assets must include USDT")
return usdt_asset
def _require_coherent_totals(
account: Mapping[str, float],
positions: list[dict[str, Any]],
close_enough: CloseEnough,
) -> None:
comparisons = (
(
account["total_unrealized_pnl"],
sum(row["unrealized_pnl"] for row in positions),
),
(
account["total_initial_margin"],
sum(row["initial_margin"] for row in positions),
),
(View on GitHub (pinned to 80ffdda44c)
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
Example fix
// before
balances = [{"asset": "USDC", "balance": "100.0"}]
// after
balances = [{"asset": "USDT", "balance": "100.0"}, {"asset": "USDC", "balance": "0.0"}] Defensive patterns
Strategy: validation
Validate before calling
def has_usdt_balance(payload: dict) -> bool:
return any(
str(row.get("asset", "")).upper() == "USDT" for row in payload.get("balances", [])
)
if not has_usdt_balance(account_payload):
raise ValueError("account has no USDT margin asset") Try / catch
try:
obs = connector.read_account_observation(...)
except UsdMObservationError as exc:
if "must include USDT" in str(exc):
logger.error("account not USDT-margined: %s", exc)
halt_trading()
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Binance USD-M Shadow Account supports USDT collateral only
- Binance USD-M account totals are incoherent
- Binance USD-M position reads are incoherent
- Binance USD-M margin mode is missing
- Binance USD-M isolated position requires positive isolated m
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/92667d8240336676.
Report an issue: GitHub.