BoundaryML/baml · error · anyhow::Error

When using 'openai-generic', you must specify a base_url

Error message

When using 'openai-generic', you must specify a base_url

What it means

The `openai-generic` provider is designed to talk to arbitrary OpenAI-compatible endpoints, so unlike the named providers it has no default host. resolve_properties requires a `base_url` option; if it is absent or null, the client cannot know where to send requests and bails with this error.

Source

Thrown at engine/baml-runtime/src/internal/llm_client/primitive/openai/properties/generic.rs:21

use anyhow::{Context, Result};

use crate::{
    internal::llm_client::{properties_hander::PropertiesHandler, AllowedMetadata},
    RuntimeContext,
};

use super::PostRequestProperties;

pub fn resolve_properties(
    mut properties: PropertiesHandler,
    ctx: &RuntimeContext,
) -> Result<PostRequestProperties> {
    let default_role = properties.pull_default_role("system")?;

    let base_url = properties.pull_base_url()?;
    let base_url = match base_url {
        Some(base_url) => base_url,
        None => anyhow::bail!("When using 'openai-generic', you must specify a base_url"),
    };
    let allowed_metadata = properties.pull_allowed_role_metadata()?;

    let headers = properties.pull_headers()?;
    let api_key = match properties.pull_api_key()? {
        Some(api_key) if !api_key.is_empty() => Some(api_key),
        _ => None,
    };
    let supported_request_modes = properties.pull_supported_request_modes()?;

    let properties = properties.finalize();

    Ok(PostRequestProperties {
        default_role,
        base_url,
        api_key,
        headers,
        properties,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Add `base_url` to the openai-generic client options (e.g. base_url "http://localhost:8000/v1").
  2. If base_url comes from an env var, confirm the variable is set in the runtime environment.
  3. If you actually meant the real OpenAI API, switch the provider to `openai` which has a default endpoint.

Example fix

// before
client<MyGeneric> {
  provider openai-generic
  options {
    api_key env.MY_KEY
  }
}
// after
client<MyGeneric> {
  provider openai-generic
  options {
    base_url "http://localhost:11434/v1"
    api_key env.MY_KEY
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// baml-cli check, or in code:
if client.provider == "openai-generic" && (client.options.base_url == null || client.options.base_url.isEmpty()) {
    throw new Error("openai-generic requires a non-empty base_url in options");
}

Try / catch

// Rust/anyhow caller
match baml_runtime::run(fn_name, params) {
    Ok(res) => res,
    Err(e) if e.to_string().contains("must specify a base_url") => {
        eprintln!("openai-generic client misconfigured: set base_url (check env vars)");
        std::process::exit(2);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Declaring a client with provider `openai-generic` in BAML without a `base_url` in its options block, or setting base_url via an expression that evaluates to null/empty (e.g. env.BASE_URL with the env var unset).

Common situations: Pointing BAML at a self-hosted or third-party OpenAI-compatible server (vLLM, Ollama, LiteLLM) and forgetting the endpoint; renaming an env var so the interpolated base_url becomes empty; copying an `openai` client config and switching only the provider string.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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