BoundaryML/baml · error · minijinja::Error
Cannot parse end date
Error message
Cannot parse end date
What it means
The date_between Jinja filter parses the row `date`, then the `begin` bound, then the `end` bound. If `end` cannot be parsed into a date by parse_date, the filter raises a minijinja SyntaxError 'Cannot parse end date'. Like the begin bound, an unparseable end is treated as a template error rather than silently false.
Solutions
- Correct the `end` argument to match the format expected by parse_date (e.g. YYYY-MM-DD)
- Pre-validate or normalize the end date in the template before calling date_between
- Check computed end expressions render to a parseable date string
- Ensure the end date is actually later-formatted correctly relative to begin (a swapped begin/end still needs valid formats)
Example fix
// before
{{ date_between(post.created_at, "2024-01-01", end_date_var) }}
// after (end_date_var = "31-12-2024" -> fix source)
{% set end_date_var = "2024-12-31" %}
{{ date_between(post.created_at, "2024-01-01", end_date_var) }} Defensive patterns
Strategy: validation
Validate before calling
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
if (!ISO_DATE.test(end)) throw new Error(`end must be YYYY-MM-DD, got: ${end}`); Try / catch
{% if end is string and end|length == 10 %}
{{ date_between(d, begin, end) }}
{% else %}
{{ false }}
{% endif %} Prevention
- Validate computed end-date expressions render parseable strings
- Keep begin and end in the same, parse_date-compatible format
- Add template smoke tests covering date_between
When it happens
Trigger: Calling date_between(date, begin, end) where `end` is not in the format parse_date accepts (wrong format, empty string, or a non-date expression).
Common situations: Templates with a mistyped or locale-formatted end date; computed end values (e.g. concatenated strings) that don't produce a valid date string.
Related errors
- Cannot parse begin date
- Expected a statically defined string, not expression
- Failed to get template
- Failed to render template
- InvalidOperation
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/358f4350eddb537a.
Report an issue: GitHub.
Appendix: source
Thrown at engine/boundary-udf/src/lib.rs:88
}
}
// NOTE: (Jesus) Could use real date type
fn date_between(date: String, begin: String, end: String) -> Result<bool, minijinja::Error> {
fn parse_date(date: &str) -> chrono::ParseResult<chrono::NaiveDate> {
chrono::NaiveDate::parse_from_str(date, "%Y-%m-%d")
}
// NOTE: (Jesus) This will be parsing `begin` and `end` dates for all rows and `date` for all date
// comparisons.
let Ok(date) = parse_date(&date) else {
return Ok(false);
};
let begin = parse_date(&begin).map_err(|_| {
minijinja::Error::new(minijinja::ErrorKind::SyntaxError, "Cannot parse begin date")
})?;
let end = parse_date(&end).map_err(|_| {
minijinja::Error::new(minijinja::ErrorKind::SyntaxError, "Cannot parse end date")
})?;
Ok(date >= begin && date <= end)
}
pub mod tests {
//! Utilities for testing
use crate::{config::UDFConfig, read_udf_config};
pub fn load_sample_udf() -> UDFConfig {
use anyhow::Context;
read_udf_config("./sample-prices.yaml")
.context("load sample UDF config")
.unwrap()
}
// NOTE: sample data in here has been generated with the help of AI.
pub mod data {View on GitHub (pinned to bd85ce9dee)