BoundaryML/baml · error

stream is not a boolean

Error message

stream is not a boolean

What it means

The optional "stream" kwarg in call_function_parse_from_c must be a boolean BAML value when provided; it controls whether streaming result types are allowed. Passing a non-boolean value (string "true", int 1, etc.) triggers this error instead of a silent coercion.

Source

Thrown at engine/language_client_cffi/src/ffi/functions.rs:180

    } = BamlFunctionArguments::from_c_buffer(encoded_args, length)?;

    let ctx = runtime.create_ctx_manager(BamlValue::String("cffi".to_string()), None);
    let text = match kwargs.get("text") {
        Some(t) => match t.as_str() {
            Some(s) => s.to_string(),
            None => {
                return Err(anyhow::anyhow!("text is not a string"));
            }
        },
        None => {
            return Err(anyhow::anyhow!("text is required"));
        }
    };
    let allow_stream_types = match kwargs.get("stream") {
        Some(s) => match s.as_bool() {
            Some(b) => b,
            None => {
                return Err(anyhow::anyhow!("stream is not a boolean"));
            }
        },
        None => false,
    };

    // Spawn an async task to await the future and call the callback when done.
    // Ensure that a Tokio runtime is running in your application.
    let rt = RUNTIME.clone();
    rt.spawn(async move {
        let result = match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| async {
            // TODO: There's a race condition bug here. Technically we should COPY the type builder, not just clone it.
            let type_builder = type_builder.map(|t| t.type_builder.as_ref().clone());
            runtime.parse_llm_response(
                func_name,
                text,
                allow_stream_types,
                &ctx,
                type_builder.as_ref(),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Pass stream as a real boolean (true/false) not a string or number
  2. If the value comes from config, cast it: bool(str_value == 'true') for strings
  3. Omit the stream kwarg entirely to use the default (False)

Example fix

// before
baml.baml_call_function_parse(rt, "fn", {"text": t, "stream": "true"})
// after
baml.baml_call_function_parse(rt, "fn", {"text": t, "stream": True})
Defensive patterns

Strategy: type-guard

Validate before calling

if "stream" in kwargs and not isinstance(kwargs["stream"], bool):
    raise TypeError("stream must be a bool")

Type guard

def is_bool(v): return isinstance(v, bool)

Try / catch

try:
    parsed = baml.baml_call_function_parse(rt, fn, kwargs)
except Exception as e:
    if 'stream is not a boolean' in str(e):
        kwargs['stream'] = kwargs['stream'] in (True, 'true', 1)
        parsed = baml.baml_call_function_parse(rt, fn, kwargs)
    else:
        raise

Prevention

When it happens

Trigger: Calling baml_call_function_parse with kwargs["stream"] set to a non-boolean BamlValue (string, number, null-object).

Common situations: Passing Python truthy values like "true"/1 instead of True, JSON configs where booleans arrived as strings, or building kwargs dynamically from untyped user config.

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/3a9e564ab4cdf583. Report an issue: GitHub.