{"record":{"id":"509ea4daaf6ee17a","repo":"HKUDS/Vibe-Trading","slug":"binance-usd-m-field-name-must-be-non-negative","errorCode":null,"errorMessage":"Binance USD-M field {name} must be non-negative","messagePattern":"Binance USD-M field (.+?) must be non-negative","errorType":"exception","errorClass":"UsdMObservationError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/binance/usdm.py","lineNumber":331,"sourceCode":"\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,\n        \"market_type\": \"usdm\",\n        \"host\": host,\n        \"account_endpoint\": \"/fapi/v2/account\",\n        \"position_endpoint\": \"/fapi/v3/positionRisk\",","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/binance/usdm.py#L313-L349","documentation":"Raised by _number when a field is numeric, finite, but negative while non_negative=True was requested (or via _integer which sets non_negative=True). Used for counts and amounts that can be zero but never negative, e.g. update indices, seat numbers, quantities. The {name} placeholder identifies the field.","triggerScenarios":"A field like updateTime, an index, or an amount is negative in the payload; e.g. positionAmt-style amounts extracted with non_negative=True, or a timestamp/count that underflowed.","commonSituations":"Sign flipped during upstream arithmetic; mock data with negative counts; API change returning -1 sentinels for 'not available'; timezone/epoch arithmetic producing negative timestamps.","solutions":["Inspect the named field in the raw payload; decide whether -1/negative is a sentinel meaning 'missing' and map it to None/0 before parsing","Fix sign handling in upstream computations","Update fixtures to non-negative values","If the exchange legitimately returns -1 sentinels, translate them before calling the connector"],"exampleFix":"// before\n_number(payload.get(\"updateTime\"), \"updateTime\", non_negative=True)  # -1\n// after\nraw = payload.get(\"updateTime\")\n_number(0 if raw == -1 else raw, \"updateTime\", non_negative=True)","handlingStrategy":"validation","validationCode":"def non_negative(v) -> float:\n    n = float(v)\n    if n < 0:\n        raise ValueError(f\"negative value: {v}\")\n    return n\n\npayload[\"updateTime\"] = max(0, payload.get(\"updateTime\", 0))","typeGuard":null,"tryCatchPattern":"try:\n    obs = connector.read_account_observation(...)\nexcept UsdMObservationError as exc:\n    if \"must be non-negative\" in str(exc):\n        payload = translate_sentinels(payload)  # -1 -> 0/None\n        obs = connector.read_account_observation(...)\n    else:\n        raise","preventionTips":["Translate exchange -1 sentinels at the ingestion layer","Use integer-safe arithmetic for counts and timestamps","Clamp computed values to >= 0 when negatives are meaningless"],"tags":["binance","usdm","negative-value","range-validation","sentinel-values"],"backgroundTag":"out-of-range-value-validation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}