{"record":{"id":"5bc30644dc2ae961","repo":"BoundaryML/baml","slug":"cannot-call-expr-function-through-call-function-impl","errorCode":null,"errorMessage":"Cannot call expr function through call_function_impl","messagePattern":"Cannot call expr function through call_function_impl","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/runtime_methods/call_function.rs","lineNumber":53,"sourceCode":"    },\n    runtime_interface::RuntimeConstructor,\n    tracing::BamlTracer,\n    tracingv2::storage::storage::{Collector, BAML_TRACER},\n    type_builder::TypeBuilder,\n    BamlRuntime, FunctionResult, FunctionResultStream, InternalRuntimeInterface,\n    RenderCurlSettings, RuntimeContext, RuntimeContextManager, TripWire,\n};\n\nimpl BamlRuntime {\n    pub(crate) async fn call_function_impl<'ir>(\n        &'ir self,\n        prepared_func_call: PreparedFunction<'ir>,\n        ctx: RuntimeContext,\n        cancel_tripwire: Arc<TripWire>,\n    ) -> Result<crate::FunctionResult> {\n        let future = async {\n            let func = prepared_func_call.func.as_ref().ok_or_else(|| {\n                anyhow::anyhow!(\"Cannot call expr function through call_function_impl\")\n            })?;\n            let renderer = PromptRenderer::from_function(func, self.ir(), &ctx)?;\n            let orchestrator = self.orchestration_graph(renderer.client_spec(), &ctx)?;\n\n            let baml_args = BamlValue::Map(prepared_func_call.baml_args.value);\n\n            // Now actually execute the code.\n            let (history, _) = orchestrate_call(\n                orchestrator,\n                self.ir(),\n                &ctx,\n                &renderer,\n                &baml_args,\n                |s| renderer.parse(self.ir(), &ctx, s, false),\n                cancel_tripwire.trip_wire(),\n            )\n            .await;\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/runtime_methods/call_function.rs#L35-L71","documentation":"BAML expression functions (`expr`-based functions with no LLM prompt) cannot be executed through `call_function_impl`, which requires a real prepared LLM function with a prompt renderer and orchestration graph. The code explicitly rejects a prepared call whose `func` is None, which is the marker for expression functions.","triggerScenarios":"Invoking a BAML expr function via the non-expr runtime path (e.g. a client/runtime `call_function` API, or call_function_with_expr_events when the prepared function turns out to be an expr function).","commonSituations":"A BAML function was refactored from an LLM prompt function into an expr function while client code still calls the generic function-call API; SDK callers using call_function on a function defined purely with `expr`.","solutions":["Route expr functions through the expr-aware path (`call_function_with_expr_events`) instead of `call_function` / call_function_impl.","If the function should be an LLM function, restore its prompt/client definition in the BAML source so it is not treated as an expr function.","Check the function's definition in baml_src: functions whose body is an expression are not streamable/callable via the generic LLM call path."],"exampleFix":"// before\nlet result = runtime.call_function(\"my_expr_fn\", params).await?; // panics into this error\n// after\nlet result = runtime.call_function_with_expr_events(\"my_expr_fn\", params).await?;","handlingStrategy":"try-catch","validationCode":"// Client code: only call generic call_function for LLM (non-expr) functions\nif is_expr_function(runtime, \"my_fn\") {\n    return call_function_with_expr_events(runtime, \"my_fn\", params).await;\n}","typeGuard":null,"tryCatchPattern":"// Rust\nmatch runtime.call_function(\"my_fn\", params).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"expr function\") => {\n        runtime.call_function_with_expr_events(\"my_fn\", params).await?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep call sites in sync when refactoring BAML functions between prompt and expr forms.","Route expr functions exclusively through expr-aware runtime APIs.","Document per-function whether it is prompt-based or expr-based in your client layer."],"tags":["rust","unsupported-operation","expr-function","runtime"],"backgroundTag":"unsupported-operation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}