BoundaryML/baml · critical

not implemented

Error message

not implemented

What it means

During a single (non-streaming) LLM call, OrchestratorNode::single_call builds a LoggedLLMRequest trace event and converts the RenderedPrompt to the log format. The RenderedPrompt::Completion arm is a todo!("not implemented"), so any completion-style prompt hits an unconditional Rust panic with the message "not implemented". This is a library-internal unimplemented path, not a user-input validation error.

Solutions

  1. Switch the client/prompt to chat style: use provider openai (chat) or another chat-capable provider and define the prompt with chat blocks instead of a raw completion string.
  2. Avoid legacy completion providers (llm.client, text-completion endpoints) with this runtime version.
  3. Upgrade baml CLI/runtime - check the changelog for completion-prompt support.
  4. If a completion provider is mandatory, wrap the call so you catch the panic at the process boundary or file an upstream issue.

Example fix

// before (baml) - completion-style prompt triggers the panic
function Complete(prompt: string) -> string {
  provider "llm-client"
  prompt #"{{ prompt }}"#
}
// after - chat-style prompt
function Complete(prompt: string) -> string {
  provider "openai"
  prompt #"
    {{ ctx.output_format }}
    User: {{ prompt }}
  "#
}
Defensive patterns

Strategy: validation

Validate before calling

# ensure the function uses a chat-style provider and chat prompt
# in clients.baml: provider must be a chat provider (openai, anthropic, azure, ...)
# not llm.client / raw completion endpoints

Try / catch

// python - guard the process boundary against the Rust panic
from baml_py import PyPanicError
try:
    result = b.Complete(prompt)
except PyPanicError as e:
    log.error("BAML internal panic (completion prompts unsupported): %s", e)
    result = fallback_chat_call(prompt)

Prevention

When it happens

Trigger: Invoking a BAML function configured with a completion-style client (provider llm.client / LLM_CLIENT or any prompt rendered as Completion rather than Chat) through the non-streaming single_call path, where the trace-event construction hits the Completion arm.

Common situations: Using legacy completion-style clients (e.g. text-completion OpenAI endpoints, AWS Bedrock completion clients) with a BAML runtime version where completion-prompt tracing is unimplemented; migrating old BAML projects that used llm.client providers onto newer runtime.

Related errors


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

Appendix: source

Thrown at engine/baml-runtime/src/internal/llm_client/orchestrator/mod.rs:220

impl WithSingleCallable for OrchestratorNode {
    async fn single_call(&self, ctx: &impl HttpContext, prompt: &RenderedPrompt) -> LLMResponse {
        // Create IDs for the function call and content
        {
            let request = LoggedLLMRequest {
                request_id: ctx.http_request_id().clone(),
                client_name: self.provider.name().to_string(),
                client_provider: self.provider.provider_name().to_string(),
                params: self.provider.request_options().clone(),
                prompt: match prompt {
                    RenderedPrompt::Chat(chat) => chat
                        .iter()
                        .map(|m| LLMChatMessage {
                            role: m.role.clone(),
                            content: m.parts.iter().map(|p| p.into()).collect(),
                        })
                        .collect(),
                    RenderedPrompt::Completion(completion) => {
                        todo!("not implemented")
                    }
                },
            };

            let event = TraceEvent::new_llm_request(
                ctx.runtime_context().call_id_stack.clone(),
                Arc::new(request),
            );
            BAML_TRACER.lock().unwrap().put(Arc::new(event));
        }

        // Possibly increment RoundRobin scope
        self.scope
            .scope
            .iter()
            .filter_map(|scope| match scope {
                ExecutionScope::RoundRobin(a, _) => Some(a),
                _ => None,

View on GitHub (pinned to bd85ce9dee)