{"record":{"id":"bf2ff9557c54df47","repo":"risingwavelabs/risingwave","slug":"invalid-date-days-days","errorCode":null,"errorMessage":"Invalid date: days: {days}","messagePattern":"Invalid date: days: (.+?)","errorType":"validation","errorClass":"InvalidParamsError","httpStatus":null,"severity":"error","filePath":"src/common/src/types/datetime.rs","lineNumber":249,"sourceCode":"/// let time = Time::from(interval);\n/// assert_eq!(time, Time::from_str(\"00:01:01.000003\").unwrap());\n///\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    )]","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/common/src/types/datetime.rs#L231-L267","documentation":"ErrorKind::Date is an internal error kind in RisingWave's datetime type conversion (src/common/src/types/datetime.rs) indicating that a day-count value cannot represent a valid date. Converting days (relative to the epoch used by chrono) into a NaiveDate failed because the day count is outside the representable date range, and the library surfaces it formatted as 'Invalid date: days: <i32>'.","triggerScenarios":"Calling date/timestamp conversion helpers such as Date::from_days or similar ToNaiveDate paths in src/common/src/types/datetime.rs with an i32 day count outside chrono's NaiveDate range (roughly days corresponding to years outside ~-262144..262143), e.g. from extreme interval arithmetic or corrupted input values.","commonSituations":"Arithmetic on dates/intervals that overflows (subtracting huge intervals); casting out-of-range numbers to date; upstream data containing garbage numeric date values.","solutions":["Validate the day count is within chrono's supported NaiveDate range before conversion.","Check the interval/date arithmetic in the query for overflow-inducing operands.","Sanitize or bound incoming numeric data before casting to date."],"exampleFix":"// before\nlet date = Date::from_days(overflowing_days);\n// after\nlet date = if days >= MIN_DAYS && days <= MAX_DAYS {\n    Date::from_days(days)\n} else {\n    return Err(ErrorCode::InvalidInputValue(format!(\"days {} out of range\", days)));\n};","handlingStrategy":"try-catch","validationCode":"// Pre-check day count against the representable date range\nconst MIN_DAYS: i32 = i32::MIN / 4; // conservatively inside chrono's range\nconst MAX_DAYS: i32 = i32::MAX / 4;\nfn days_in_range(days: i32) -> bool { (MIN_DAYS..=MAX_DAYS).contains(&days) }","typeGuard":null,"tryCatchPattern":"match Date::from_days(days) {\n    Ok(d) => d,\n    Err(e) if e.to_string().starts_with(\"Invalid date: days\") => {\n        // fall back to NULL / sentinel date and log the raw value\n        log::warn!(\"unrepresentable date days={days}\");\n        Date::default()\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Bound interval/date arithmetic operands so day counts cannot explode.","Validate numeric columns before casting to DATE.","Add unit tests for extreme interval arithmetic paths."],"tags":["datetime","date","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"}