BoundaryML/baml · error

Expected a schema

Error message

Expected a schema

What it means

format_schema parses the BAML source with a pest-generated BAMLParser expecting a Rule::schema at the top; schema.next() returned None (empty parse) so the code raises "Expected a schema" via ok_or. This means the input could not yield any top-level schema pair — typically empty or unparseable input at the very start of parsing.

Source

Thrown at engine/baml-lib/ast/src/formatter/mod.rs:33

};
use pretty::RcDoc;
use regex::Regex;

use crate::parser::{BAMLParser, Rule};

pub struct FormatOptions {
    pub indent_width: isize,
    pub fail_on_unhandled_rule: bool,
}

pub fn format_schema(source: &str, format_options: FormatOptions) -> Result<String> {
    let ignore_directive_regex = Regex::new(r"(?i)baml-format\s*:\s*ignore")?;
    if ignore_directive_regex.is_match(source) {
        return Ok(source.to_string());
    }

    let mut schema = BAMLParser::parse(Rule::schema, source)?;
    let schema_pair = schema.next().ok_or(anyhow!("Expected a schema"))?;
    if schema_pair.as_rule() != Rule::schema {
        return Err(anyhow!("Expected a schema"));
    }

    let formatter = Formatter {
        indent_width: format_options.indent_width,
        fail_on_unhandled_rule: format_options.fail_on_unhandled_rule,
    };

    let doc = formatter.schema_to_doc(schema_pair.into_inner())?;
    let mut w = Vec::new();
    doc.render(10, &mut w)
        .map_err(|_| anyhow!("Failed to render doc"))?;
    String::from_utf8(w).map_err(|_| anyhow!("Failed to convert to string"))
}

macro_rules! next_pair {
    ($pairs:ident, $rule:expr) => {{

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure the source passed to the formatter is a non-empty BAML schema
  2. Check for empty/truncated .baml files before running format
  3. If the file should be valid, look for earlier parse errors (BAMLParser::parse would fail first) — an empty result usually means empty input
  4. Add a pre-check: skip formatting when the source is blank

Example fix

// before
let formatted = format_schema(source, options)?;
// after
if source.trim().is_empty() {
    return Ok(source.to_string());
}
let formatted = format_schema(source, options)?;
Defensive patterns

Strategy: validation

Validate before calling

if (source.trim().length === 0) { skip formatting; }

Type guard

function hasSchema(src) { return typeof src === 'string' && src.trim().length > 0; }

Try / catch

try { formatted = format_schema(src, opts); } catch (e) { if (e.message.includes('Expected a schema')) return src; throw e; }

Prevention

When it happens

Trigger: Calling format_schema / the formatter (baml-cli format, format_document, assert_format_eq) with an empty string, whitespace-only input, or input that pest cannot match as a schema at all.

Common situations: Running the formatter on an empty .baml file; a formatter hook receiving empty editor buffers; corrupted or truncated source passed to the formatting pipeline.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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