{"record":{"id":"32dbde17dd0186d4","repo":"HKUDS/Vibe-Trading","slug":"binance-usd-m-margin-mode-is-missing","errorCode":null,"errorMessage":"Binance USD-M margin mode is missing","messagePattern":"Binance USD-M margin mode is missing","errorType":"exception","errorClass":"UsdMObservationError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/binance/usdm.py","lineNumber":199,"sourceCode":"            ),\n        )\n        if any(open_order_margins):\n            raise UsdMObservationError(\"Binance USD-M Shadow Account requires zero open-order margin\")\n        for account_field, risk_field in (\n            (\"positionInitialMargin\", \"positionInitialMargin\"),\n            (\"maintMargin\", \"maintMargin\"),\n            (\"unrealizedProfit\", \"unRealizedProfit\"),\n        ):\n            if not close_enough(\n                _number(account_row.get(account_field), account_field),\n                _number(risk_row.get(risk_field), risk_field),\n            ):\n                raise UsdMObservationError(\"Binance USD-M position reads are incoherent\")\n        if str(risk_row.get(\"marginAsset\") or \"\").upper() != \"USDT\":\n            raise UsdMObservationError(\"Binance USD-M Shadow Account supports USDT collateral only\")\n        isolated = account_row.get(\"isolated\")\n        if not isinstance(isolated, bool):\n            raise UsdMObservationError(\"Binance USD-M margin mode is missing\")\n        isolated_margin = _number(\n            risk_row.get(\"isolatedMargin\"),\n            \"isolatedMargin\",\n            non_negative=True,\n        )\n        if isolated and isolated_margin == 0:\n            raise UsdMObservationError(\"Binance USD-M isolated position requires positive isolated margin\")\n        if not isolated and isolated_margin != 0:\n            raise UsdMObservationError(\"Binance USD-M cross position must report zero isolated margin\")\n        result.append(\n            {\n                \"symbol\": _canonical_symbol(raw_symbol),\n                \"quantity\": quantity,\n                \"entry_price\": entry_price,\n                \"leverage\": _number(account_row.get(\"leverage\"), \"leverage\", positive=True),\n                \"margin_mode\": \"isolated\" if isolated else \"cross\",\n                \"isolated_margin\": isolated_margin if isolated else None,\n                \"unrealized_pnl\": _number(risk_row.get(\"unRealizedProfit\"), \"unRealizedProfit\"),","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/binance/usdm.py#L181-L217","documentation":"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.","triggerScenarios":"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.","commonSituations":"Version drift after a Binance API change; response post-processing (custom JSON normalization) converting booleans to strings; incomplete test fixtures.","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"],"exampleFix":"# before (fixture)\n{\"symbol\": \"BTCUSDT\", \"isolated\": \"true\", ...}\n# after\n{\"symbol\": \"BTCUSDT\", \"isolated\": true, ...}","handlingStrategy":"validation","validationCode":"acct = await client.futures_account()\nfor p in acct['positions']:\n    if not isinstance(p.get('isolated'), bool):\n        raise RuntimeError(f\"isolated field not boolean for {p['symbol']}: {p.get('isolated')!r}\")","typeGuard":"def has_boolean_isolated(row: dict) -> bool:\n    return isinstance(row.get('isolated'), bool)","tryCatchPattern":"try:\n    obs = await connector.read_account_observation()\nexcept UsdMObservationError as e:\n    if \"margin mode is missing\" in str(e):\n        logger.error(\"response middleware likely mangled booleans: %r\", e)\n    raise","preventionTips":["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"],"tags":["binance","futures","type-validation","boolean-field"],"backgroundTag":"schema-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}