databendlabs/databend · info
midnight is valid
Error message
midnight is valid
What it means
string_to_timestamp_tz parses timestamp text; when the text is a bare date (YYYY-MM-DD), it treats it as midnight in the session timezone via date.and_hms_opt(0,0,0). The expect('midnight is valid') fires only if chrono cannot construct midnight on the parsed date — impossible for any NaiveDate that successfully parsed from %Y-%m-%d, making it an invariant assertion rather than an input check.
Solutions
- No caller action needed; input issues surface as ErrorCode::BadBytes or the check_input_year error instead.
- Keep the format constant '%Y-%m-%d' in sync with and_hms_opt usage if refactoring.
Defensive patterns
Strategy: validation
Validate before calling
// Not required; bare-date inputs return proper errors for bad UTF-8/year. let ts = string_to_timestamp_tz(text, &tz)?;
Prevention
- No guard needed; invalid timestamps surface as ErrorCode::BadBytes or year-check errors, not this panic.
When it happens
Trigger: Effectively never: any NaiveDate parseable from '%Y-%m-%d' supports 00:00:00. Could only fire on chrono regression or if the parsing path is changed to allow out-of-range hour components.
Common situations: Not user-reachable; encountered only when modifying the parse formats or chrono versions.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- clamped timestamp is inside the chrono range
- Invalid temp table desc
- internal error: entered unreachable code
- internal error: entered unreachable code
- internal error: entered unreachable code
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/3678db255fd30329.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/expression/src/types/timestamp_tz.rs:267
build_timestamp_tz(micros, resolved.offset_seconds)
}
#[inline]
pub fn string_to_timestamp_tz<'a, F: FnOnce() -> &'a Tz>(
ts_str: &[u8],
fn_tz: F,
) -> databend_common_exception::Result<timestamp_tz> {
if let Some(parsed) = try_parse_standard_timestamp_with_offset(ts_str) {
return parsed;
}
let text = std::str::from_utf8(ts_str)
.map_err(|_| ErrorCode::BadBytes("Timestamp text is not valid UTF-8".to_string()))?
.trim();
// A bare date is midnight in the session timezone.
if let Ok(date) = NaiveDate::parse_from_str(text, "%Y-%m-%d") {
let local = date.and_hms_opt(0, 0, 0).expect("midnight is valid");
return timestamp_tz_from_local(&local, fn_tz());
}
for format in PARSE_FORMATS_WITH_OFFSET {
if let Ok(value) = DateTime::parse_from_str(text, format) {
check_input_year(value.year())?;
check_timezone_offset(value.offset().local_minus_utc())?;
let micros = i128::from(value.timestamp()) * 1_000_000
+ i128::from(value.timestamp_subsec_micros());
return build_timestamp_tz(micros, value.offset().local_minus_utc());
}
}
for format in PARSE_FORMATS_NAIVE {
if let Ok(local) = NaiveDateTime::parse_from_str(text, format) {
return timestamp_tz_from_local(&local, fn_tz());
}
}View on GitHub (pinned to 288d84d76e)