HKUDS/Vibe-Trading · error · UsdMObservationError
Binance USD-M Shadow Account supports the USDT asset only
Error message
Binance USD-M Shadow Account supports the USDT asset only
What it means
A non-USDT asset row in the futures assets array has a non-zero balance in any tracked balance field. The Shadow Account supports USDT collateral only, so any leftover non-USDT balance (dust, USDC, BUSD, BNB fee balances) is rejected.
Source
Thrown at agent/src/trading/connectors/binance/usdm.py:251
balance_fields = (
"walletBalance",
"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
- Convert/transfer all non-USDT balances out of the futures wallet (use Binance's Convert-to-USDT or transfer to spot)
- Disable multi-assets mode so only USDT collateral applies
- Start with a clean sub-account funded solely with USDT
- Sweep BNB and other dust via the conversion endpoint
Example fix
# before: wallet holds {USDT: 5000, USDC: 12.3}
# after: convert or transfer out
POST /sapi/v1/asset/dust (or futures transfer) -> wallet holds {USDT: 5012.3} Defensive patterns
Strategy: validation
Validate before calling
acct = await client.futures_account()
nonzero = [a['asset'] for a in acct['assets'] if a['asset'].upper() != 'USDT' and any(float(a.get(f, 0) or 0) != 0 for f in ('balance', 'availableBalance', 'crossUnPnl'))]
if nonzero:
raise RuntimeError(f"non-USDT balances present: {nonzero}") Type guard
def wallet_is_usdt_only(assets: list[dict]) -> bool:
return all(
str(a.get('asset', '')).upper() == 'USDT'
or all(float(a.get(f, 0) or 0) == 0 for f in ('balance', 'availableBalance', 'crossUnPnl'))
for a in assets
) Try / catch
try:
obs = await connector.read_account_observation()
except UsdMObservationError as e:
if "USDT asset only" in str(e):
raise RuntimeError("convert or transfer out non-USDT futures balances, then retry")
raise Prevention
- Keep the futures wallet funded with USDT only
- Sweep dust/airdrops via Convert before onboarding the account
- Use a fresh dedicated sub-account for the Shadow Account
When it happens
Trigger: Holding residual USDC/BUSD/BNB in the futures wallet; airdropped dust; receiving multi-asset collateral; auto-conversion settings leaving non-USDT balances.
Common situations: Prior trading on multi-asset mode, BNB fee discount balances, unswept conversion dust, or using the same account previously with USDC-margined contracts.
Related errors
- Binance USD-M position reads are incoherent
- Binance USD-M Shadow Account supports USDT collateral only
- Binance USD-M margin mode is missing
- Binance USD-M isolated position requires positive isolated m
- Binance USD-M cross position must report zero isolated margi
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/6ae1b7c6c096a4f8.
Report an issue: GitHub.