BoundaryML/baml · error

OpenAI transcription field `response_format` must be a…

Error message

OpenAI transcription field `response_format` must be a string

What it means

optional_response_format accepts either a missing response_format or a string; any other JSON type (number, bool, object, array) makes BAML throw this error. It is a type check on the `response_format` property of an OpenAI transcription client before the request is sent.

Solutions

  1. Quote the response_format value so it is a string ("json").
  2. Remove response_format from the properties if it is not needed.
  3. If the value is computed, ensure it serializes to a JSON string.

Example fix

// before
response_format true

// after
response_format "json"
Defensive patterns

Strategy: validation

Validate before calling

if (props.response_format !== undefined && typeof props.response_format !== 'string') {
  throw new Error('response_format must be a string (e.g. "json")');
}

Type guard

const isResponseFormat = (v: unknown): v is 'json' | undefined =>
  v === undefined || v === 'json';

Try / catch

try {
  await baml.transcribe(...);
} catch (e) {
  if (String(e).includes('response_format must be a string')) {
    console.error('Quote response_format, e.g. response_format "json"');
  }
  throw e;
}

Prevention

When it happens

Trigger: Providing response_format in the BAML transcription client properties as a non-string JSON value, e.g. response_format true or response_format 1.

Common situations: Boolean-style config authored without quotes, generated configs that serialize the format as a number, or mixing up response_format with a different client's option.

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/65bf3d317a09bfd6. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-runtime/src/internal/llm_client/primitive/openai/types.rs:201

fn optional_response_format(
    properties: &BamlMap<String, Value>,
    model: &str,
) -> Result<Option<String>> {
    match properties.get("response_format") {
        Some(Value::String(value))
            if value == "json"
                || (value == "verbose_json"
                    && !matches!(
                        model,
                        "gpt-4o-transcribe"
                            | "gpt-4o-mini-transcribe"
                            | "gpt-4o-mini-transcribe-2025-12-15"
                            | "gpt-4o-transcribe-diarize"
                    )) => Ok(Some(value.clone())),
        Some(Value::String(value)) => bail!(
            "OpenAI transcription response_format `{value}` is not supported by model `{model}` in BAML; use `json`"
        ),
        Some(_) => bail!("OpenAI transcription field `response_format` must be a string"),
        None => Ok(None),
    }
}

fn optional_temperature(properties: &BamlMap<String, Value>) -> Result<Option<String>> {
    match properties.get("temperature") {
        Some(Value::Number(value)) => Ok(Some(value.to_string())),
        Some(Value::String(value)) => Ok(Some(value.clone())),
        Some(_) => bail!("OpenAI transcription field `temperature` must be a number or string"),
        None => Ok(None),
    }
}

fn filename_for_mime(mime: &str) -> String {
    let subtype = mime
        .split('/')
        .next_back()
        .unwrap_or("mpeg")

View on GitHub (pinned to bd85ce9dee)