{"record":{"id":"b0127f18b0c42d76","repo":"risingwavelabs/risingwave","slug":"invalid-time-secs-secs-nanoseconds-nsecs","errorCode":null,"errorMessage":"Invalid time: secs: {secs}, nanoseconds: {nsecs}","messagePattern":"Invalid time: secs: (.+?), nanoseconds: (.+?)","errorType":"validation","errorClass":"InvalidParamsError","httpStatus":null,"severity":"error","filePath":"src/common/src/types/datetime.rs","lineNumber":251,"sourceCode":"///\n/// let interval = Interval::from_month_day_usec(0, 0, -61000003);\n/// let time = Time::from(interval);\n/// assert_eq!(time, Time::from_str(\"23:58:58.999997\").unwrap());\n/// ```\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}","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/common/src/types/datetime.rs#L233-L269","documentation":"ErrorKind::Time is an internal error kind in RisingWave's datetime type conversion (src/common/src/types/datetime.rs) indicating a time-of-day value with seconds/nanoseconds that cannot form a valid NaiveTime. The conversion via Time::from_num_seconds_from_midnight requires secs < 86400 and nsecs < 1_000_000_000; violating either produces 'Invalid time: secs: <u32>, nanoseconds: <u32>'.","triggerScenarios":"Calling Time conversion helpers (e.g. Time::from_num_seconds_from_midnight or from-unchecked counterparts guarded by validation in src/common/src/types/datetime.rs) with secs >= 86400 or nsecs >= 1_000_000_000, typically from numeric casts of user data.","commonSituations":"Casting raw epoch-second values to TIME; passing nanosecond-precision values into a microsecond field; computed time arithmetic that exceeds one day without normalization.","solutions":["Ensure secs < 86400 and nsecs < 1_000_000_000 before conversion (normalize with modulo/reminding).","Convert seconds-of-day values via date-aware timestamp functions instead of direct TIME casting.","Sanitize numeric input data before casting to TIME."],"exampleFix":"// before\nlet time = Time::with_secs_nanos(90000, 0)?;\n// after\nlet time = Time::with_secs_nanos(secs % 86400, 0)?;","handlingStrategy":"validation","validationCode":"// Pre-check time components before conversion\nfn valid_time(secs: u32, nsecs: u32) -> bool {\n    secs < 86_400 && nsecs < 1_000_000_000\n}","typeGuard":null,"tryCatchPattern":"match Time::from_num_seconds_from_midnight(secs, nano) {\n    Ok(t) => t,\n    Err(e) if e.to_string().starts_with(\"Invalid time: secs\") => {\n        log::warn!(\"invalid time secs={secs} nsecs={nsecs}, normalizing\");\n        Time::from_num_seconds_from_midnight(secs % 86_400, nsecs % 1_000_000_000)?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Normalize seconds-of-day with modulo 86400 before TIME conversion.","Never feed epoch timestamps directly into TIME casts; use timestamp functions.","Validate nanosecond fields are < 1e9 when accepting external precision data."],"tags":["datetime","time","range","risingwave"],"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"}