{"record":{"id":"7b3f24927b0a5392","repo":"nautechsystems/nautilus_trader","slug":"invalid-negative-binance-field-timestamp-value","errorCode":null,"errorMessage":"invalid negative Binance {field} timestamp: {value}","messagePattern":"invalid negative Binance (.+?) timestamp: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/parse.rs","lineNumber":90,"sourceCode":"const CONTRACT_TYPE_CURRENT_QUARTER: &str = \"CURRENT_QUARTER\";\nconst CONTRACT_TYPE_NEXT_QUARTER: &str = \"NEXT_QUARTER\";\n\npub(crate) fn parse_millis(value: i64, field: &str) -> anyhow::Result<UnixNanos> {\n    parse_timestamp(value, UnixNanos::from_millis_checked(value), field)\n}\n\npub(crate) fn parse_micros(value: i64, field: &str) -> anyhow::Result<UnixNanos> {\n    parse_timestamp(value, UnixNanos::from_micros_checked(value), field)\n}\n\nfn parse_timestamp(\n    value: i64,\n    timestamp: Option<UnixNanos>,\n    field: &str,\n) -> anyhow::Result<UnixNanos> {\n    timestamp.ok_or_else(|| {\n        if value < 0 {\n            anyhow::anyhow!(\"invalid negative Binance {field} timestamp: {value}\")\n        } else {\n            anyhow::anyhow!(\"Binance {field} timestamp is outside the UnixNanos range: {value}\")\n        }\n    })\n}\n\npub(crate) fn parse_millis_or_init(value: i64, field: &str, ts_init: UnixNanos) -> UnixNanos {\n    timestamp_or_init(parse_millis(value, field), ts_init)\n}\n\npub(crate) fn parse_micros_or_init(value: i64, field: &str, ts_init: UnixNanos) -> UnixNanos {\n    timestamp_or_init(parse_micros(value, field), ts_init)\n}\n\nfn timestamp_or_init(timestamp: anyhow::Result<UnixNanos>, ts_init: UnixNanos) -> UnixNanos {\n    match timestamp {\n        Ok(timestamp) => timestamp,\n        Err(e) => {","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/common/parse.rs#L72-L108","documentation":"parse_timestamp converts an i64 epoch value into UnixNanos. When the parsed millis/micros value overflows or cannot be represented, it returns None, and this error is raised if that value was negative — a negative timestamp is semantically invalid for Binance fields.","triggerScenarios":"Calling parse_millis or parse_micros with a negative i64 from a Binance API field (e.g. time, updateTime, transactTime) — usually from corrupted data, mocked responses with -1 sentinels, or arithmetic producing negative epoch values.","commonSituations":"Test fixtures using -1 as a 'missing' sentinel; deserialization of corrupted responses; clock bugs producing negative derived timestamps; fields defaulting to negative values when absent.","solutions":["Check the source JSON field for the negative value and fix the upstream data or fixture.","Treat missing timestamps explicitly (e.g. use Option or parse_millis_or_init) instead of negative sentinels.","Validate timestamps are >= 0 before passing them into the parser.","Verify clock synchronization if timestamps are computed locally."],"exampleFix":"// before\nlet ts = parse_millis(-1, \"updateTime\")?;\n\n// after\nlet ts = if raw_update_time >= 0 {\n    parse_millis(raw_update_time, \"updateTime\")?\n} else {\n    return Err(anyhow::anyhow!(\"updateTime missing from event\"));\n};","handlingStrategy":"validation","validationCode":"fn is_plausible_ts(v: i64) -> bool { v >= 0 && v < 4_102_444_800_000 } // until year 2100, millis","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use negative sentinels like -1 for missing timestamps; use Option.","Range-check timestamps parsed from external events.","Keep clocks NTP-synchronized."],"tags":["binance","timestamp","validation","parsing"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}