{"record":{"id":"fb3464d21b5d3eb2","repo":"HKUDS/Vibe-Trading","slug":"binance-usd-m-field-name-must-be-finite","errorCode":null,"errorMessage":"Binance USD-M field {name} must be finite","messagePattern":"Binance USD-M field (.+?) must be finite","errorType":"exception","errorClass":"UsdMObservationError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/binance/usdm.py","lineNumber":327,"sourceCode":"def _canonical_symbol(symbol: str) -> str:\n    if not symbol.endswith(\"USDT\") or len(symbol) <= 4 or not symbol.isalnum():\n        raise UsdMObservationError(\"Binance USD-M supports canonical */USDT symbols only\")\n    return f\"{symbol[:-4]}-USDT-PERP\"\n\n\ndef _number(\n    value: Any,\n    name: str,\n    *,\n    non_negative: bool = False,\n    positive: bool = False,\n) -> float:\n    try:\n        number = float(value)\n    except (TypeError, ValueError) as exc:\n        raise UsdMObservationError(f\"Binance USD-M field {name} must be numeric\") from exc\n    if not math.isfinite(number):\n        raise UsdMObservationError(f\"Binance USD-M field {name} must be finite\")\n    if positive and number <= 0:\n        raise UsdMObservationError(f\"Binance USD-M field {name} must be positive\")\n    if non_negative and number < 0:\n        raise UsdMObservationError(f\"Binance USD-M field {name} must be non-negative\")\n    return number\n\n\ndef _integer(value: Any, name: str) -> int:\n    number = _number(value, name, non_negative=True)\n    if not number.is_integer():\n        raise UsdMObservationError(f\"Binance USD-M field {name} must be an integer\")\n    return int(number)\n\n\ndef _configuration_hash(source_profile: str, host: str, absolute_tolerance: float) -> str:\n    payload = {\n        \"schema_version\": SCHEMA_VERSION,\n        \"source_profile\": source_profile,","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/binance/usdm.py#L309-L345","documentation":"Raised by _number when a field converts to float successfully but the result is not finite (NaN or +/-Inf). JSON parsers accept tokens like 'NaN'/'Infinity' or Python float('nan'), so this guard catches them before they poison downstream arithmetic. The {name} placeholder identifies which field (price, balance, positionAmt, etc.) is non-finite.","triggerScenarios":"A payload field is the string 'NaN' or 'Infinity' (Python's float() accepts these), or a computed/upstream value already containing NaN is fed back into the connector.","commonSituations":"Upstream components dividing by zero to produce NaN/inf and passing it along; exchange sending literal NaN in rare degenerate snapshots; fixtures using float('nan'); string interpolation of 'Infinity' from log-adjacent code.","solutions":["Trace where the NaN/Infinity originated — usually an upstream division by zero or unset field","Sanitize inputs: convert non-finite values to a rejected/zero default before passing payloads to the connector","Fix fixtures that use float('nan') or 'Infinity' strings","If the exchange genuinely sent NaN, retry the snapshot and report to Binance if persistent"],"exampleFix":"// before\nrow = {\"symbol\": \"BTCUSDT\", \"positionAmt\": \"NaN\"}\n// after\nrow = {\"symbol\": \"BTCUSDT\", \"positionAmt\": \"0\"}","handlingStrategy":"validation","validationCode":"import math\n\ndef all_finite(row: dict, keys: list[str]) -> bool:\n    return all(\n        math.isfinite(float(row[k])) for k in keys if row.get(k) is not None\n    )\n\nif not all_finite(row, [\"positionAmt\", \"entryPrice\"]):\n    row = sanitize(row)  # drop/zero non-finite values","typeGuard":"import math\n\ndef is_finite_number(value: Any) -> TypeGuard[float]:\n    try:\n        return math.isfinite(float(value))\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    obs = connector.read_account_observation(...)\nexcept UsdMObservationError as exc:\n    if \"must be finite\" in str(exc):\n        row = coerce_non_finite_to_zero(row)\n        obs = connector.read_account_observation(...)  # retry with sanitized data\n    else:\n        raise","preventionTips":["Filter NaN/Inf at ingestion boundaries (math.isfinite checks)","Avoid float('nan') sentinel values in pipelines; use None","Test fixtures must not contain 'NaN'/'Infinity' strings"],"tags":["binance","usdm","nan","infinity","numeric-validation"],"backgroundTag":"non-finite-number-validation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}