HKUDS/Vibe-Trading · error · UsdMObservationError
Binance USD-M margin mode is missing
Error message
Binance USD-M margin mode is missing
What it means
The account row's isolated field must be a real boolean (true/false). If it is missing, None, or arrives as the string "true"/"false" or "isolated"/"cross", isinstance(isolated, bool) fails and this error is raised.
Source
Thrown at agent/src/trading/connectors/binance/usdm.py:199
),
)
if any(open_order_margins):
raise UsdMObservationError("Binance USD-M Shadow Account requires zero open-order margin")
for account_field, risk_field in (
("positionInitialMargin", "positionInitialMargin"),
("maintMargin", "maintMargin"),
("unrealizedProfit", "unRealizedProfit"),
):
if not close_enough(
_number(account_row.get(account_field), account_field),
_number(risk_row.get(risk_field), risk_field),
):
raise UsdMObservationError("Binance USD-M position reads are incoherent")
if str(risk_row.get("marginAsset") or "").upper() != "USDT":
raise UsdMObservationError("Binance USD-M Shadow Account supports USDT collateral only")
isolated = account_row.get("isolated")
if not isinstance(isolated, bool):
raise UsdMObservationError("Binance USD-M margin mode is missing")
isolated_margin = _number(
risk_row.get("isolatedMargin"),
"isolatedMargin",
non_negative=True,
)
if isolated and isolated_margin == 0:
raise UsdMObservationError("Binance USD-M isolated position requires positive isolated margin")
if not isolated and isolated_margin != 0:
raise UsdMObservationError("Binance USD-M cross position must report zero isolated margin")
result.append(
{
"symbol": _canonical_symbol(raw_symbol),
"quantity": quantity,
"entry_price": entry_price,
"leverage": _number(account_row.get("leverage"), "leverage", positive=True),
"margin_mode": "isolated" if isolated else "cross",
"isolated_margin": isolated_margin if isolated else None,
"unrealized_pnl": _number(risk_row.get("unRealizedProfit"), "unRealizedProfit"),View on GitHub (pinned to 80ffdda44c)
Solutions
- Log the raw account row to see what type isolated actually is
- If a proxy/transform layer converts booleans, fix it to preserve native JSON types
- Update the library if Binance changed the field format
- In tests/fixtures, use real booleans for isolated
Example fix
# before (fixture)
{"symbol": "BTCUSDT", "isolated": "true", ...}
# after
{"symbol": "BTCUSDT", "isolated": true, ...} Defensive patterns
Strategy: validation
Validate before calling
acct = await client.futures_account()
for p in acct['positions']:
if not isinstance(p.get('isolated'), bool):
raise RuntimeError(f"isolated field not boolean for {p['symbol']}: {p.get('isolated')!r}") Type guard
def has_boolean_isolated(row: dict) -> bool:
return isinstance(row.get('isolated'), bool) Try / catch
try:
obs = await connector.read_account_observation()
except UsdMObservationError as e:
if "margin mode is missing" in str(e):
logger.error("response middleware likely mangled booleans: %r", e)
raise Prevention
- Do not transform JSON responses between fetch and library ingestion
- Use real booleans in fixtures and mocks
- Pin the library version matched to the current Binance API schema
When it happens
Trigger: Binance changing the field's JSON type (e.g. serializing it as a string), a middleware/proxy mangling the response, or a mocked/test payload using strings instead of booleans.
Common situations: Version drift after a Binance API change; response post-processing (custom JSON normalization) converting booleans to strings; incomplete test fixtures.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Binance USD-M position reads are incoherent
- Binance USD-M Shadow Account supports USDT collateral only
- Binance USD-M isolated position requires positive isolated m
- Binance USD-M cross position must report zero isolated margi
- Binance USD-M assets must include exactly one USDT row
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/32dbde17dd0186d4.
Report an issue: GitHub.