{"record":{"id":"c96ee8d71a229d83","repo":"risingwavelabs/risingwave","slug":"invalid-datetime-seconds-secs-nanoseconds-n","errorCode":null,"errorMessage":"Invalid datetime: seconds: {secs}, nanoseconds: {nsecs}","messagePattern":"Invalid datetime: seconds: (.+?), nanoseconds: (.+?)","errorType":"validation","errorClass":"InvalidParamsError","httpStatus":null,"severity":"error","filePath":"src/common/src/types/datetime.rs","lineNumber":255,"sourceCode":"/// ```\nimpl From<Interval> for Time {\n    fn from(interval: Interval) -> Self {\n        let usecs = interval.usecs_of_day();\n        let secs = (usecs / 1_000_000) as u32;\n        let nano = (usecs % 1_000_000 * 1000) as u32;\n        Time::from_num_seconds_from_midnight_uncheck(secs, nano)\n    }\n}\n\n#[derive(Copy, Clone, Debug, Error)]\nenum ErrorKind {\n    #[error(\"Invalid date: days: {days}\")]\n    Date { days: i32 },\n    #[error(\"Invalid time: secs: {secs}, nanoseconds: {nsecs}\")]\n    Time { secs: u32, nsecs: u32 },\n    #[error(\"Invalid time: {value} {unit} is out of range for a time of day\")]\n    TimeOfDay { value: u64, unit: &'static str },\n    #[error(\"Invalid datetime: seconds: {secs}, nanoseconds: {nsecs}\")]\n    DateTime { secs: i64, nsecs: u32 },\n    #[error(\"Invalid datetime: {value} {unit} is out of range\")]\n    Timestamp { value: i64, unit: &'static str },\n    #[error(\"Can't cast string to date (expected format is YYYY-MM-DD)\")]\n    ParseDate,\n    #[error(\n        \"Can't cast string to time (expected format is HH:MM:SS[.D+{{up to 6 digits}}][Z] or HH:MM)\"\n    )]\n    ParseTime,\n    #[error(\n        \"Can't cast string to timestamp (expected format is YYYY-MM-DD HH:MM:SS[.D+{{up to 9 digits}}] or YYYY-MM-DD HH:MM or YYYY-MM-DD or ISO 8601 format)\"\n    )]\n    ParseTimestamp,\n}\n\n#[derive(Debug, Error)]\n#[error(transparent)]\npub struct InvalidParamsError(#[from] ErrorKind);","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/common/src/types/datetime.rs#L237-L273","documentation":"ErrorKind::DateTime is raised by Timestamp::with_secs_nsecs when chrono's DateTime::from_timestamp(secs, nsecs) returns None, i.e. the seconds/nanoseconds pair does not represent a representable UTC datetime (secs out of i64-supported range or nsecs >= 1_000_000_000). It is wrapped in InvalidParamsError and bubbles up through Timestamp deserialization.","triggerScenarios":"Calling Timestamp::with_secs_nsecs(secs, nsecs) with an out-of-range secs (near i64::MIN/MAX) or nsecs >= 1e9; Time-stamped protobuf decoding (Timestamp::from_protobuf, V1 format) of a corrupted payload.","commonSituations":"Corrupted or hand-crafted protobuf messages; external systems emitting epoch values far outside the supported range; off-by-one nanosecond arithmetic bugs producing nsecs == 1_000_000_000.","solutions":["Validate nsecs < 1_000_000_000 and that secs is within chrono's supported range before constructing.","Normalize nanosecond overflow by carrying it into secs (secs += nsecs / 1e9; nsecs %= 1e9).","Verify the protobuf encoder/writer version matches the decoder (V0 micros vs V1 secs+nsecs format)."],"exampleFix":"// before\nlet ts = Timestamp::with_secs_nsecs(secs, nsecs)?;\n// after\nlet ts = Timestamp::with_secs_nsecs(secs + (nsecs / 1_000_000_000) as i64, nsecs % 1_000_000_000)?;","handlingStrategy":"validation","validationCode":"fn can_be_timestamp(secs: i64, nsecs: u32) -> bool {\n    nsecs < 1_000_000_000 && (-8334601228800..=8210266876799).contains(&secs)\n}","typeGuard":"fn is_safe_epoch_pair(secs: i64, nsecs: u32) -> Option<(i64, u32)> {\n    if nsecs >= 1_000_000_000 { None } else { Some((secs, nsecs)) }\n}","tryCatchPattern":"match Timestamp::with_secs_nsecs(secs, nsecs) {\n    Ok(ts) => ts,\n    Err(e) => return Err(anyhow!(\"bad timestamp payload: {e}\")),\n}","preventionTips":["Carry nanosecond overflow into seconds before construction.","Treat protobuf payloads as untrusted; validate before decode-dependent construction.","Keep encoder/decoder versions in sync (V0 vs V1 timestamp format)."],"tags":["rust","timestamp","protobuf","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}