BoundaryML/baml · error · minijinja::Error
InvalidOperation
InvalidOperation
Error message
Invalid delimiter '{}'. Use 'comma', 'tab', or 'pipe' What it means
BAML's toon encoding filter accepts a 'delimiter' kwarg restricted to the strings 'comma', 'tab', or 'pipe', which map to toon::Delimiter variants. Any other string raises a minijinja InvalidOperation error naming the rejected value and the allowed options.
Solutions
- Use one of the accepted names: delimiter="comma", delimiter="tab", or delimiter="pipe".
- Check case and whitespace — the match is exact lowercase; 'Tab' or ' tab ' fail.
- If you need a different delimiter, post-process the TOON output (e.g. replace the delimiter after encoding).
- Remove the delimiter kwarg to use the default delimiter.
- Validate user-supplied template kwargs before rendering if delimiter comes from config.
Example fix
// before (template)
{{ rows | toon(delimiter=";") }}
// after
{{ rows | toon(delimiter="pipe") }} {# or comma / tab #} Defensive patterns
Strategy: validation
Validate before calling
fn valid_delimiter(d: &str) -> bool {
matches!(d, "comma" | "tab" | "pipe")
}
if !valid_delimiter(&delimiter) { bail!("delimiter must be comma|tab|pipe"); } Type guard
fn valid_delimiter(d: &str) -> bool { matches!(d, "comma" | "tab" | "pipe") } Try / catch
match tpl.render(ctx) {
Ok(out) => out,
Err(e) if e.kind() == minijinja::ErrorKind::InvalidOperation
&& e.to_string().contains("Invalid delimiter") => render_with_default_delimiter(),
Err(e) => return Err(e.into()),
} Prevention
- Use only the literal names comma, tab, pipe — exact lowercase, no whitespace.
- Do not pass raw delimiter characters (';', '\t'); pass their names.
- Omit the kwarg to accept the default delimiter.
- Validate user-configured delimiter values before template rendering.
When it happens
Trigger: Calling the toon filter with delimiter set to anything other than the three accepted names — e.g. delimiter=";", delimiter="\t" (literal tab character), "tab " with whitespace, or capitalized "Tab".
Common situations: Users trying to use semicolons or custom delimiters for TOON output, passing the actual delimiter character instead of its symbolic name, or copying config from another tool with different delimiter vocabulary.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Cannot parse begin date
- Cannot parse end date
- Expected a statically defined string, not expression
- Failed to get template
- Failed to render template
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/886ca0fee9e5fee0.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-lib/jinja-runtime/src/lib.rs:148
value: &minijinja::Value,
kwargs: &Kwargs,
) -> Result<String, minijinja::Error> {
let json_value = minijinja_value_to_json(value)
.map_err(|e| minijinja::Error::new(minijinja::ErrorKind::BadSerialization, e))?;
let mut options = toon::EncodeOptions::default();
if let Ok(indent) = kwargs.get::<usize>("indent") {
options.indent = indent;
}
if let Ok(delimiter_str) = kwargs.get::<String>("delimiter") {
options.delimiter = match delimiter_str.as_str() {
"comma" => toon::Delimiter::Comma,
"tab" => toon::Delimiter::Tab,
"pipe" => toon::Delimiter::Pipe,
_ => {
return Err(minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
format!(
"Invalid delimiter '{}'. Use 'comma', 'tab', or 'pipe'",
delimiter_str
),
))
}
};
}
if let Ok(marker) = kwargs.get::<String>("length_marker") {
if marker.chars().count() == 1 {
options.length_marker = marker.chars().next();
} else {
return Err(minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
format!("length_marker must be a single character, got '{}'", marker),
));View on GitHub (pinned to bd85ce9dee)