BoundaryML/baml · error

while condition must be boolean

Error message

while condition must be boolean

What it means

A while loop's condition expression must evaluate to a boolean on every iteration. The interpreter matches the evaluated condition against Bool(true) to continue and Bool(false) to break; any other value type is rejected with this error rather than being truthiness-coerced.

Solutions

  1. Wrap the condition in an explicit boolean comparison, e.g. while count > 0 instead of while count
  2. Check each iteration's value path (including early returns and null branches) so the condition always yields a bool
  3. If the condition involves a function call, ensure that function returns a boolean on all paths

Example fix

// before
while remaining {
  ...
}
// after
while remaining > 0 {
  ...
}
Defensive patterns

Strategy: type-guard

Validate before calling

fn validate_while_condition(v: &BamlValue) -> Result<(), String> {
    match v { BamlValue::Bool(_) => Ok(()), other => Err(format!("while condition must be bool, got {:?}", other)) }
}

Type guard

fn is_boolean(v: &BamlValue) -> bool { matches!(v, BamlValue::Bool(_)) }

Prevention

When it happens

Trigger: A while condition expression that evaluates to a non-boolean value — e.g. while count, while list, while some_string, or a condition whose branches can return null/int on some iteration (often the first or a later iteration, not necessarily the first).

Common situations: Porting truthy-conditional loops from Python/JS into BAML; conditions returning optional values that become null mid-loop; forgetting a comparison operator in the condition.

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


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/93a3be9d05c8d3bc. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-compiler/src/thir/interpret.rs:765

                                    scopes,
                                    thir,
                                    run_llm_function,
                                    watch_handler,
                                    function_name,
                                )
                                .await?
                                {
                                    ControlFlow::Break => break,
                                    ControlFlow::Continue => continue,
                                    ControlFlow::Normal(_) => {}
                                    ControlFlow::Return(val) => {
                                        scopes.pop();
                                        return Ok(Some(ControlFlow::Return(val)));
                                    }
                                }
                            }
                            BamlValueWithMeta::Bool(false, _) => break,
                            _ => bail!("while condition must be boolean"),
                        }
                    },
                    Statement::ForLoop {
                        identifier,
                        iterator,
                        block,
                        ..
                    } => {
                        let iterable_val = expect_value(
                            evaluate_expr(
                                iterator,
                                scopes,
                                thir,
                                run_llm_function,
                                watch_handler,
                                function_name,
                            )
                            .await?,

View on GitHub (pinned to bd85ce9dee)