BoundaryML/baml · error
Filter function ' ' must return a boolean, got
Error message
Filter function '{}' must return a boolean, got {:?} What it means
A @watch filter function must evaluate to a boolean so the interpreter can decide whether the watched value changed meaningfully. After executing the filter body, evaluate_filter_function checks the result; any non-Bool result (string, int, null, etc.) triggers this error.
Solutions
- Make the filter's final expression an explicit boolean comparison (==, !=, >, <, etc.)
- Coerce/normalize early-return paths to return true or false
- Log or inspect the returned value ({:?} in the message shows the actual type) to find which path yields a non-bool
Example fix
// before
function changed(v: string) -> bool { v.length() }
// after
function changed(v: string) -> bool { v.length() > 0 } Defensive patterns
Strategy: type-guard
Validate before calling
fn validate_filter_returns_bool(f: &FunctionDef) -> Result<(), String> {
match f.return_type { Type::Bool => Ok(()), other => Err(format!("filter must return bool, got {:?}", other)) }
} Type guard
fn is_bool_result(v: &BamlValue) -> bool { matches!(v, BamlValue::Bool(_)) } Prevention
- End every filter function with an explicit boolean comparison
- Make all early-return paths return true or false
- Avoid relying on truthiness of ints/strings; BAML does not coerce
- Annotate filter functions with a bool return type so mismatches surface earlier
When it happens
Trigger: A filter function whose last evaluated expression yields a non-boolean — e.g. returning a comparison result wrapped in a value, returning an int used as truthy, or forgetting a final comparison expression.
Common situations: Filters written in languages where numbers/strings are truthy (e.g. returning value.length() directly); returning null on an early path; forgetting the final boolean expression in an implicit-return block.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Filter function ' ' must take exactly 1 parameter (current…
- while condition must be boolean
- array access on non-list at
- array assignment on non-list value at
- attempted to call non-function
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b827eeb78ba291ea.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:394
let noop_watch_handler = crate::watch::shared_noop_handler();
// Evaluate the function body
let result = evaluate_block(
&filter_func.body,
scopes,
thir,
run_llm_function,
&noop_watch_handler,
function_name,
)
.await?;
scopes.pop();
// Extract boolean result
match result {
BamlValueWithMeta::Bool(b, _) => Ok(b),
_ => bail!(
"Filter function '{}' must return a boolean, got {:?}",
fn_name,
result
),
}
}
/// Convert BamlValue to BamlValueWithMeta (with fake metadata)
fn baml_value_to_value_with_meta(value: BamlValue) -> BamlValueWithMeta<ExprMetadata> {
let meta = (Span::fake(), None);
match value {
BamlValue::String(s) => BamlValueWithMeta::String(s, meta),
BamlValue::Int(i) => BamlValueWithMeta::Int(i, meta),
BamlValue::Float(f) => BamlValueWithMeta::Float(f, meta),
BamlValue::Bool(b) => BamlValueWithMeta::Bool(b, meta),
BamlValue::Map(m) => {
let converted = m
.into_iter()View on GitHub (pinned to bd85ce9dee)