{"record":{"id":"e311489122cf93f9","repo":"BoundaryML/baml","slug":"cannot-parse-begin-date","errorCode":null,"errorMessage":"Cannot parse begin date","messagePattern":"Cannot parse begin date","errorType":"exception","errorClass":"minijinja::Error","httpStatus":null,"severity":"error","filePath":"engine/boundary-udf/src/lib.rs","lineNumber":85,"sourceCode":"    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {\n        // Use the pointer address to hash the expression\n        std::ptr::hash(self.0, state);\n    }\n}\n\n// NOTE: (Jesus) Could use real date type\nfn date_between(date: String, begin: String, end: String) -> Result<bool, minijinja::Error> {\n    fn parse_date(date: &str) -> chrono::ParseResult<chrono::NaiveDate> {\n        chrono::NaiveDate::parse_from_str(date, \"%Y-%m-%d\")\n    }\n\n    // NOTE: (Jesus) This will be parsing `begin` and `end` dates for all rows and `date` for all date\n    // comparisons.\n    let Ok(date) = parse_date(&date) else {\n        return Ok(false);\n    };\n    let begin = parse_date(&begin).map_err(|_| {\n        minijinja::Error::new(minijinja::ErrorKind::SyntaxError, \"Cannot parse begin date\")\n    })?;\n    let end = parse_date(&end).map_err(|_| {\n        minijinja::Error::new(minijinja::ErrorKind::SyntaxError, \"Cannot parse end date\")\n    })?;\n\n    Ok(date >= begin && date <= end)\n}\n\npub mod tests {\n    //! Utilities for testing\n    use crate::{config::UDFConfig, read_udf_config};\n\n    pub fn load_sample_udf() -> UDFConfig {\n        use anyhow::Context;\n        read_udf_config(\"./sample-prices.yaml\")\n            .context(\"load sample UDF config\")\n            .unwrap()\n    }","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/boundary-udf/src/lib.rs#L67-L103","documentation":"The date_between Jinja filter parses the row `date`, then the `begin` bound, then the `end` bound. If `begin` cannot be parsed into a date by parse_date, the filter raises a minijinja SyntaxError 'Cannot parse begin date' instead of returning false (the row date itself failing to parse silently yields false).","triggerScenarios":"Calling date_between(date, begin, end) where `begin` is not in the format parse_date accepts (wrong format, empty string, or a non-date expression).","commonSituations":"Templates passing user-supplied or locale-formatted begin dates; hardcoded date strings using a format different from what parse_date expects (e.g. YYYY/MM/DD vs YYYY-MM-DD).","solutions":["Correct the `begin` argument to match the format expected by parse_date (e.g. YYYY-MM-DD)","Pre-validate or normalize the begin date in the template before calling date_between","Log/print the failing begin value to confirm what is actually passed","If the value is dynamic, wrap the filter call so a parse error surfaces the raw input"],"exampleFix":"// before\n{{ date_between(post.created_at, \"01/02/2024\", \"31/02/2024\") }}\n// after\n{{ date_between(post.created_at, \"2024-02-01\", \"2024-02-29\") }}","handlingStrategy":"validation","validationCode":"const ISO_DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\nif (!ISO_DATE.test(begin)) throw new Error(`begin must be YYYY-MM-DD, got: ${begin}`);","typeGuard":null,"tryCatchPattern":"{% if begin is string and begin|length == 10 %}\n  {{ date_between(d, begin, end) }}\n{% else %}\n  {{ false }}\n{% endif %}","preventionTips":["Normalize all template date arguments to the format parse_date expects","Use ISO 8601 (YYYY-MM-DD) consistently for date strings","Unit-test template filters with realistic date inputs"],"tags":["jinja","date","template"],"backgroundTag":"invalid-date-format","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}