BerriAI/litellm · error · ValueError

Invalid YAML frontmatter

Error message

Invalid YAML frontmatter: {e}

What it means

While loading a .prompt file, _parse_frontmatter runs re.match for the leading '---' delimiters and feeds the captured block to yaml.safe_load; any YAML syntax error is re-raised as ValueError('Invalid YAML frontmatter: ...'). Only YAML errors are wrapped here — structural issues (no delimiters) instead fall through to 'entire content is template'.

Solutions

  1. Run yaml.safe_load on the text between the '---' lines in isolation to reproduce and see the exact parser message
  2. Fix indentation to spaces only, and quote any value containing a colon or special character
  3. Validate prompt files in CI with a small script that parses each file's frontmatter
  4. If loading via prompt_directory, remember failures are swallowed — check manager.prompts.keys() after init to confirm the file actually registered

Example fix

# before — prompts/greeting.prompt
---
name: greeting
question: What: is your name?
---
Hello {{user}}

# after
---
name: greeting
question: "What: is your name?"
---
Hello {{user}}
Defensive patterns

Strategy: try-catch

Validate before calling

import re, yaml

def validate_prompt_file(path):
    text = Path(path).read_text()
    m = re.match(r'^---\s*\n(.*?)\n---\s*\n(.*)$', text, re.DOTALL)
    if m:
        yaml.safe_load(m.group(1))  # raises YAMLError with position info
    return True

Try / catch

try:
    template = manager._load_prompt_file(path, prompt_id)
except ValueError as e:
    if 'Invalid YAML frontmatter' in str(e):
        logger.error('frontmatter syntax error in %s: %s', path, e)
        raise

Prevention

When it happens

Trigger: A .prompt file whose frontmatter contains tab indentation, an unquoted colon inside a value, unclosed quotes/brackets, or duplicate keys. Editing prompts by hand or generating them from templates that mangle whitespace. Loading via prompt_directory, where this error surfaces during __init__ — but note the directory loader catches per-file exceptions silently, so via a directory this instead manifests later as 'Prompt ... not found'; via prompt_file it propagates.

Common situations: Copy-pasting frontmatter from docs that converted spaces to tabs; question-style default values ('question: What: is your name?'); YAML treating 'no'/'on' as booleans only after other syntax broke; editors auto-stripping trailing spaces inside the block.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/4d5c6b490dd9f728. Report an issue: GitHub.

Appendix: source

Thrown at litellm/integrations/dotprompt/prompt_manager.py:175

            content=template_content.strip(),
            metadata=frontmatter,
            template_id=prompt_id,
        )

    def _parse_frontmatter(self, content: str) -> tuple[dict[str, Any], str]:
        """Parse YAML frontmatter from prompt content."""
        # Match YAML frontmatter between --- delimiters
        frontmatter_pattern: Final = r"^---\s*\n(.*?)\n---\s*\n(.*)$"
        match: Final = re.match(frontmatter_pattern, content, re.DOTALL)

        if match:
            frontmatter_yaml: Final = match.group(1)
            template_content = match.group(2)

            try:
                frontmatter = yaml.safe_load(frontmatter_yaml) or {}
            except yaml.YAMLError as e:
                raise ValueError(f"Invalid YAML frontmatter: {e}")
        else:
            # No frontmatter found, treat entire content as template
            frontmatter = {}
            template_content = content

        return frontmatter, template_content

    def render(
        self,
        prompt_id: str,
        prompt_variables: dict[str, Any] | None = None,
        version: int | None = None,
    ) -> str:
        """
        Render a prompt template with the given variables.

        Args:
            prompt_id: The ID of the prompt template to render

View on GitHub (pinned to 77b7c6c40c)