{"record":{"id":"8052a9d06f79aacb","repo":"HKUDS/Vibe-Trading","slug":"exc-8052a9","errorCode":null,"errorMessage":"{exc}","messagePattern":"\\{exc\\}","errorType":"exception","errorClass":"BinanceConfigError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/binance/sdk.py","lineNumber":703,"sourceCode":"\ndef _reject_unsupported_usdm_surface(cfg: BinanceConfig) -> None:\n    if cfg.market_type == \"usdm\":\n        raise BinanceConfigError(\n            \"Binance USD-M Shadow Account exposes account and position reads only\"\n        )\n\n\ndef _get_usdm_observation(cfg: BinanceConfig, exchange: Any) -> dict[str, Any]:\n    try:\n        return read_account_observation(\n            exchange,\n            source_profile=\"binance-live-sdk-readonly\",\n            host=cfg.host,\n            now=_utc_now,\n            absolute_tolerance=cfg.observation_absolute_tolerance,\n        )\n    except UsdMObservationError as exc:\n        raise BinanceConfigError(str(exc)) from None\n\n\ndef _exchange(cfg: BinanceConfig):\n    \"\"\"Build a ccxt Binance client bound to the configured market/environment.\"\"\"\n    ccxt = _require_ccxt()\n    client_config: dict[str, Any] = {\n        \"apiKey\": cfg.api_key,\n        \"secret\": cfg.api_secret,\n        \"enableRateLimit\": True,\n        \"timeout\": int(cfg.timeout * 1000),\n        # Signed Binance requests have a narrow timestamp window. Let ccxt\n        # measure the exchange clock before the first private request so a\n        # sleeping laptop or an imperfect system clock does not force users to\n        # reconnect or recreate an otherwise valid read-only API key.\n        \"options\": {\n            \"adjustForTimeDifference\": True,\n            \"recvWindow\": 10_000,\n        },","sourceCodeStart":685,"sourceCodeEnd":721,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/binance/sdk.py#L685-L721","documentation":"Raised when _get_usdm_observation wraps any UsdMObservationError from read_account_observation into BinanceConfigError via `raise BinanceConfigError(str(exc)) from None`. It is a re-translation at the SDK boundary: the underlying USD-M observation (account read, payload validation, or coherence check) failed, and the connector reports it as a configuration error. The `from None` suppresses the original traceback, so the message string is the only clue to the root cause.","triggerScenarios":"Calling get_account_snapshot() or get_positions() on a usdm market_type config where read_account_observation raises UsdMObservationError: invalid tolerance settings, non-mapping account payload from fapiprivatev2_get_account(), non-list position risk from fapiprivatev3_get_positionrisk(), multi-asset margin enabled, non-zero open-order margin, or incoherent account vs USDT asset totals.","commonSituations":"Testnet/live account with multi-assets margin toggled on in Binance futures settings; existing open orders on the account (non-zero totalOpenOrderInitialMargin); API key permissions returning truncated payloads; misconfigured observation_absolute_tolerance (NaN or negative); ccxt version drift changing fapiprivate response shapes.","solutions":["Check the wrapped message text — it identifies which underlying UsdMObservationError fired (multi-asset margin, open-order margin, payload shape, or totals coherence) and fix that condition on the account/config","Log/inspect the raw exchange.fapiprivatev2_get_account() and fapiprivatev3_get_positionrisk() responses to see which invariant broke","Ensure observation_absolute_tolerance is a non-negative finite float in the config","If the shadow-account invariants (no open orders, single-asset margin) are intentionally unsupported, route to a different snapshot code path or document the limitation"],"exampleFix":"# before\nsnapshot = sdk.get_account_snapshot(cfg)  # BinanceConfigError: multi-asset margin...\n\n# after\ntry:\n    snapshot = sdk.get_account_snapshot(cfg)\nexcept BinanceConfigError as exc:\n    logger.error(\"usdm observation failed: %s\", exc)\n    raise\n# then disable multi-assets margin on the Binance futures account or set observation_absolute_tolerance >= 0","handlingStrategy":"try-catch","validationCode":"# before calling: pre-verify the observation invariants cheaply\nfrom trading.connectors.binance.usdm import read_account_observation\ntry:\n    read_account_observation(ex, source_profile=cfg.profile, host=cfg.host, now=_utc_now,\n                             absolute_tolerance=cfg.observation_absolute_tolerance)\nexcept UsdMObservationError as e:\n    logger.warning('usdm observation will fail: %s', e)","typeGuard":"def is_usdm_snapshot_ok(snapshot: object) -> bool:\n    return isinstance(snapshot, Mapping) and all(\n        isinstance(snapshot.get(k), (int, float)) for k in\n        ('wallet_balance', 'margin_balance', 'available_balance'))","tryCatchPattern":"try:\n    snapshot = sdk.get_account_snapshot(cfg)\nexcept BinanceConfigError as exc:\n    if 'observation' in str(exc) or 'USD-M' in str(exc):\n        logger.error('usdm observation invariant violated: %s', exc)\n        alert_ops(exc)\n    raise","preventionTips":["Keep the USD-M account in single-asset (USDT) margin mode","Cancel all open orders before requesting snapshots","Validate observation_absolute_tolerance at config load time","Log the full message; the wrapped UsdMObservationError text names the exact invariant"],"tags":["binance","usdm-futures","account-snapshot","config-error","fail-closed"],"backgroundTag":"account-state-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}