{"record":{"id":"4cba3e62645e3d92","repo":"nautechsystems/nautilus_trader","slug":"seconds-timestamp-should-fit-i64","errorCode":null,"errorMessage":"seconds timestamp should fit i64","messagePattern":"seconds timestamp should fit i64","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/generators/client_order_id.rs","lineNumber":58,"sourceCode":"            + \"-\".len()\n            + strategy_tag.len()\n            + \"-\".len()\n    } else {\n        \"O\".len() + DATETIME_TAG_COMPACT_LEN + trader_tag.len() + strategy_tag.len()\n    }\n}\n\n/// Slow path across second boundaries: rebuilds the fixed prefix directly in the output buffer.\nfn write_fixed_prefix(\n    buf: &mut String,\n    trader_tag: &str,\n    strategy_tag: &str,\n    use_hyphens: bool,\n    epoch_second: u64,\n) {\n    let now_utc = Offset::UTC.to_datetime(\n        Timestamp::from_second(\n            i64::try_from(epoch_second).expect(\"seconds timestamp should fit i64\"),\n        )\n        .expect(\"seconds timestamp should be within valid range\"),\n    );\n\n    buf.clear();\n\n    if use_hyphens {\n        write!(\n            buf,\n            \"O-{:04}{:02}{:02}-{:02}{:02}{:02}-{trader_tag}-{strategy_tag}-\",\n            now_utc.year(),\n            now_utc.month(),\n            now_utc.day(),\n            now_utc.hour(),\n            now_utc.minute(),\n            now_utc.second(),\n        )\n        .expect(\"writing to String should not fail\");","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/generators/client_order_id.rs#L40-L76","documentation":"The client order ID generator formats a UTC timestamp prefix and converts the epoch seconds (u64) to i64 for jiff's Timestamp::from_second. The expect panics when the u64 epoch second exceeds i64::MAX — the system clock is absurdly far in the future (year ~292 billion).","triggerScenarios":"Calling write_fixed_prefix (via refresh_fixed_prefix) with epoch_second larger than i64::MAX, which only occurs if SystemTime/clock supplies an astronomically large value.","commonSituations":"Corrupt or mocked clocks returning huge values; fuzzing or property tests feeding u64::MAX timestamps; integer-overflow bugs upstream.","solutions":["Fix the source of the bogus timestamp (system clock or mocked clock)","Clamp/saturate the epoch second to i64 range before formatting: i64::try_from(sec).unwrap_or(i64::MAX)","Add an upstream validity check (epoch_second within a sane range) before generating IDs","If this comes from a test, use a realistic timestamp in the mock clock"],"exampleFix":"// before\nlet now_utc = Offset::UTC.to_datetime(\n    Timestamp::from_second(\n        i64::try_from(epoch_second).expect(\"seconds timestamp should fit i64\"),\n    )...\n// after\nlet sec = i64::try_from(epoch_second).unwrap_or(i64::MAX);","handlingStrategy":"validation","validationCode":"fn plausible_epoch_second(sec: u64) -> bool {\n    // between 2000-01-01 and year 2100\n    (946_684_800..=4_102_444_800).contains(&sec)\n}","typeGuard":null,"tryCatchPattern":"// Pre-check before generating IDs from a clock value\nlet sec = now_sec();\nassert!(plausible_epoch_second(sec), \"implausible clock value: {sec}\");","preventionTips":["Sanity-check clock values against a plausible window before use in IDs","Fix mocks/fuzz generators to emit realistic timestamps","Saturate rather than expect when converting u64 epoch seconds to i64"],"tags":["rust","panic","timestamp","clock"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}