{"record":{"id":"85a956233effedc7","repo":"nautechsystems/nautilus_trader","slug":"invalid-timestamp","errorCode":null,"errorMessage":"Invalid timestamp","messagePattern":"Invalid timestamp","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/redis/queries.rs","lineNumber":1064,"sourceCode":"        }\n        Value::Array(arr) => {\n            for item in arr {\n                convert_timestamps(item);\n            }\n        }\n        _ => {}\n    }\n}\n\nfn convert_timestamp_strings(value: &mut Value) {\n    match value {\n        Value::Object(map) => {\n            for (key, v) in map {\n                if is_timestamp_field(key)\n                    && let Value::String(s) = v\n                    && let Ok(dt) = s.parse::<Timestamp>()\n                {\n                    let nanos = u64::try_from(dt.as_nanosecond()).expect(\"Invalid timestamp\");\n                    *v = Value::Number(nanos.into());\n                }\n                convert_timestamp_strings(v);\n            }\n        }\n        Value::Array(arr) => {\n            for item in arr {\n                convert_timestamp_strings(item);\n            }\n        }\n        _ => {}\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::str::FromStr;\n","sourceCodeStart":1046,"sourceCodeEnd":1082,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/redis/queries.rs#L1046-L1082","documentation":"In the Redis payload deserializer, `convert_timestamp_strings` parses timestamp-named string fields back into u64 nanoseconds via Jiff's `Timestamp` and then converts to u64 with `u64::try_from`. The expect() panics when the parsed timestamp is negative (pre-1970) or otherwise cannot be represented as an unsigned nanosecond count, i.e. the stored string was not a valid forward-direction Unix timestamp.","triggerScenarios":"Calling `deserialize_payload` on a cached JSON blob whose timestamp field contains a malformed or pre-epoch string (e.g. \"-123\", \"1970-01-01T00:00:00-05:00\" with negative epoch, arbitrary text that happens to parse as Timestamp), or a string written by a different serializer format than `serialize_payload` produces.","commonSituations":"Redis cache populated by another application or older schema version; manual edits to cached values; timezone-offset strings whose instant is before the epoch; mixed-language clients writing ISO strings with different precision.","solutions":["Inspect the cached value and correct or delete the malformed timestamp string","Ensure the writer used `serialize_payload`'s `{dt:.9}` UTC format; migrate old entries or bump the cache key/version","Replace the expect with a logged skip/error so one bad field does not abort deserialization of the whole payload","Validate strings with `s.parse::<Timestamp>()` plus a range check (>= 0 nanos) before the try_from"],"exampleFix":"// before\nlet nanos = u64::try_from(dt.as_nanosecond()).expect(\"Invalid timestamp\");\n// after\nmatch u64::try_from(dt.as_nanosecond()) {\n    Ok(nanos) => *v = Value::Number(nanos.into()),\n    Err(_) => log::warn!(\"invalid timestamp string {s} for key {key}; leaving as string\"),\n}","handlingStrategy":"validation","validationCode":"fn parse_ts_field(s: &str) -> Option<u64> {\n    s.parse::<Timestamp>().ok()\n        .and_then(|dt| u64::try_from(dt.as_nanosecond()).ok())\n}","typeGuard":"fn is_valid_timestamp_string(s: &str) -> bool {\n    s.parse::<Timestamp>().map(|dt| dt.as_nanosecond() >= 0).unwrap_or(false)\n}","tryCatchPattern":"match u64::try_from(dt.as_nanosecond()) {\n    Ok(nanos) => *v = Value::Number(nanos.into()),\n    Err(_) => log::warn!(\"invalid timestamp string '{s}' for key '{key}'\"),\n}","preventionTips":["Write timestamps with the canonical `{dt:.9}` UTC format only","Never hand-edit cached payload JSON; invalidate and rewrite instead","Validate round-trip (serialize then deserialize) in tests","Reject pre-epoch timestamps at write time"],"tags":["rust","redis","timestamp","deserialization","panic"],"backgroundTag":"invalid-date-format","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"}