BoundaryML/baml · error · anyhow::Error

Either base_url or both (resource_name, deployment_id) must

Error message

Either base_url or both (resource_name, deployment_id) must be provided

What it means

When resolving Azure OpenAI client properties, BAML requires exactly one way to build the endpoint: either an explicit `base_url`, or both `resource_name` and `deployment_id` (from which the standard Azure URL is constructed). Supplying none of them, or a partial/mixed combination (e.g. base_url plus resource_name, or resource_name without deployment_id), makes the configuration ambiguous or incomplete, so resolve_properties fails fast with this bail.

Source

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

) -> Result<PostRequestProperties> {
    // POST https://{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}

    let default_role = properties.pull_default_role("system")?;
    let allowed_metadata = properties.pull_allowed_role_metadata()?;

    let base_url = properties.pull_base_url()?;
    let resource_name = properties.remove_str("resource_name")?;
    let deployment_id = properties.remove_str("deployment_id")?;
    let api_version = properties.remove_str("api_version")?;

    // Ensure that either (resource_name, deployment_id) or base_url is provided
    let base_url = match (base_url, resource_name, deployment_id) {
        (Some(base_url), None, None) => base_url,
        (None, Some(resource_name), Some(deployment_id)) => {
            format!("https://{resource_name}.openai.azure.com/openai/deployments/{deployment_id}")
        }
        _ => {
            anyhow::bail!("Either base_url or both (resource_name, deployment_id) must be provided")
        }
    };

    let api_key = properties
        .pull_api_key()?
        .or_else(|| ctx.env.get("AZURE_OPENAI_API_KEY").map(|s| s.to_string()));
    let mut headers = properties.pull_headers()?;
    if let Some(api_key) = &api_key {
        headers.insert("API-KEY".to_string(), api_key.clone());
    }
    let headers = headers;

    let mut query_params = HashMap::new();
    if let Some(v) = api_version {
        query_params.insert("api-version".to_string(), v.to_string());
    };

    let supported_request_modes = properties.pull_supported_request_modes()?;

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Set both resource_name and deployment_id on the Azure client (and remove base_url if present).
  2. Alternatively set a single base_url property and remove resource_name/deployment_id.
  3. Verify property names are spelled exactly (base_url, resource_name, deployment_id) so the values are actually pulled.
  4. If using Azure OpenAI via a proxy/gateway, provide its full base_url instead of the Azure resource fields.

Example fix

// before
client<MyAzure> {
  provider azure-openai
  options {
    resource_name "my-res"
    api_key env.AZURE_OPENAI_API_KEY
  }
}
// after
client<MyAzure> {
  provider azure-openai
  options {
    resource_name "my-res"
    deployment_id "my-gpt4o"
    api_key env.AZURE_OPENAI_API_KEY
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Go-style check before constructing the Azure client options
func validateAzureOpts(baseURL, resourceName, deploymentID string) error {
    hasURL := baseURL != ""
    hasName := resourceName != ""
    hasDep := deploymentID != ""
    if hasURL && (hasName || hasDep) {
        return fmt.Errorf("use either base_url OR (resource_name + deployment_id), not both")
    }
    if !hasURL && !(hasName && hasDep) {
        return fmt.Errorf("azure client needs base_url or both resource_name and deployment_id")
    }
    return nil
}

Prevention

When it happens

Trigger: Configuring an `azure` OpenAI client in clients.baml where: (a) none of base_url/resource_name/deployment_id are set; (b) only resource_name is set without deployment_id; (c) only deployment_id is set; (d) base_url is combined with resource_name and/or deployment_id (the match arms require None for the others).

Common situations: Copying an Azure client config from docs but forgetting the deployment_id; switching from the URL-based form to resource_name form and leaving a stale base_url; env-var-driven configs where AZURE_OPENAI_API_KEY is set but the endpoint fields were never provided; typos in property names so the fields resolve to None.

Related errors


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