getzola/zola · error

Error parsing YAML datetime

Error message

Error parsing YAML datetime

What it means

`parse_yaml_datetime` parses datetime strings from YAML front matter using the `YAML_DATETIME_RE` regex (accepting ISO-8601-like `YYYY-MM-DD[Thh:mm[:ss[.frac]][Z|±hh:mm]]` forms). If the string does not match the regex at all, this generic error is raised. YAML's unquoted `date: 2024-01-01` scalar type is a known source of oddities since serde_yaml may decode it as a string only in specific formats.

Source

Thrown at components/content/src/front_matter/datetime.rs:17

use std::sync::LazyLock;

use errors::{Result, anyhow};
use regex::Regex;
use serde::Deserialize;
use time::format_description::well_known::Rfc3339;

// See https://github.com/getzola/zola/issues/2071#issuecomment-1530610650
static YAML_DATETIME_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r#"^"?(?P<year>[0-9]{4})-(?P<month>[0-9][0-9]?)-(?P<day>[0-9][0-9]?)(?:(?:[Tt]|[ \t]+)(?P<hour>[0-9][0-9]?):(?P<minute>[0-9]{2}):(?P<second>[0-9]{2})(?P<fraction>\.[0-9]{0,9})?[ \t]*(?:(?P<utc>Z)|(?P<offset>(?P<offset_hour>[-+][0-9][0-9]?)(?::(?P<offset_minute>[0-9][0-9]))?))?)?"?$"#).unwrap()
});

fn parse_yaml_datetime(date_string: &str) -> Result<time::OffsetDateTime> {
    let captures = if let Some(captures_) = YAML_DATETIME_RE.captures(date_string) {
        Ok(captures_)
    } else {
        Err(anyhow!("Error parsing YAML datetime"))
    }?;
    let year = captures.name("year").unwrap().as_str();
    let month = captures.name("month").unwrap().as_str();
    let day = captures.name("day").unwrap().as_str();
    let hour = if let Some(hour_) = captures.name("hour") { hour_.as_str() } else { "0" };
    let minute = if let Some(minute_) = captures.name("minute") { minute_.as_str() } else { "0" };
    let second = if let Some(second_) = captures.name("second") { second_.as_str() } else { "0" };
    let fraction_raw =
        if let Some(fraction_) = captures.name("fraction") { fraction_.as_str() } else { "" };
    let fraction_intermediate = fraction_raw.trim_end_matches("0");
    //
    // Prepare for eventual conversion into nanoseconds
    let fraction = if !fraction_intermediate.is_empty() { fraction_intermediate } else { "0" };
    let maybe_timezone_hour = captures.name("offset_hour");
    let maybe_timezone_minute = captures.name("offset_minute");

    let mut offset_datetime = time::OffsetDateTime::UNIX_EPOCH;

View on GitHub (pinned to 61d3082821)

Solutions

  1. Use ISO 8601 format in front matter: `date = 2024-01-01` or `date = 2024-01-01T10:30:00Z`
  2. Check for typos/extra characters in the date string (slashes, month names, trailing spaces)
  3. If a custom field, quote it consistently and keep to `YYYY-MM-DD[Thh:mm[:ss]][Z|±hh:mm]`

Example fix

// before (front matter)
date: 2024/01/01
// after
date: 2024-01-01
Defensive patterns

Strategy: validation

Validate before calling

use regex::Regex;
let yaml_dt = Regex::new(r"^\d{4}-\d{2}-\d{2}([Tt ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?([Zz]|[+-]\d{2}:?\d{2})?)?$").unwrap();
if !yaml_dt.is_match(date_str) { /* fix front matter format before parsing */ }

Type guard

fn looks_like_yaml_datetime(s: &str) -> bool {
    s.len() >= 10 && s[..4].chars().all(|c| c.is_ascii_digit()) && s.as_bytes().get(4) == Some(&b'-') && s.as_bytes().get(7) == Some(&b'-')
}

Try / catch

match parse_yaml_datetime(s) {
    Ok(dt) => dt,
    Err(e) if e.to_string() == "Error parsing YAML datetime" =>
        bail!("Front matter date '{}' must be ISO 8601, e.g. 2024-01-01T10:30:00Z", s),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A front-matter field expected to be a datetime (e.g. `date`, or a serialized datetime in extra/page data) contains a string that doesn't match the YAML datetime regex — wrong format, extra text, or an unsupported timezone form.

Common situations: Writing `date: 2024/01/01` (slashes instead of hyphens); including a locale-formatted date like `date: Jan 1, 2024`; quoting issues that leave stray characters; a datetime field fed a plain string like "today".

Related errors


AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03). Data as JSON: /api/errors/eb98801e3ef2a093. Report an issue: GitHub.