OpenBB-finance/OpenBB · error · ValueError
Unmatched braces in prompt content: {open_braces} opening, {
Error message
Unmatched braces in prompt content: {open_braces} opening, {close_braces} closing What it means
Pydantic validation error on PromptConfigModel.content: the template's literal brace counts differ ({ count != } count). Templates use {argument} placeholders, so unbalanced braces imply a malformed placeholder or stray brace that would break rendering. This is a naive count check — it does not validate argument references, only balance.
Source
Thrown at openbb_platform/extensions/mcp_server/openbb_mcp_server/models/mcp_config.py:112
arguments: list[ArgumentDefinitionModel] = Field(
default_factory=list, description="Argument definitions for the prompt"
)
tags: list[str] = Field(
default_factory=list, description="Tags for categorizing the prompt"
)
@field_validator("content")
@classmethod
def validate_content(cls, v: str) -> str:
"""Validate content is not empty and contains valid template syntax."""
if not v.strip():
raise ValueError("Prompt content cannot be empty")
# Check for unmatched braces
open_braces = v.count("{")
close_braces = v.count("}")
if open_braces != close_braces:
raise ValueError(
f"Unmatched braces in prompt content: {open_braces} opening, {close_braces} closing"
)
return v
@field_validator("name")
@classmethod
def validate_name(cls, v: str | None) -> str | None:
"""Validate prompt name if provided."""
if v is not None:
if not v.strip():
raise ValueError("Prompt name cannot be empty string")
# Check for valid identifier-like name
if not re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", v.strip()):
raise ValueError(f"Prompt name '{v}' should be a valid identifier")
return v
@field_validator("tags")View on GitHub (pinned to 3e071fcc2c)
Solutions
- Pair every opening brace with a closing one: fix {symbol → {symbol}.
- For literal braces in the prompt text, double them ({{ }}) if the renderer supports escaping, or restructure the text to avoid braces.
- Run a quick brace-count check locally before loading the config.
Example fix
# before
content: "Fetch data for {symbol and return JSON"
# after
content: "Fetch data for {symbol} and return JSON" Defensive patterns
Strategy: validation
Validate before calling
def braces_balanced(template: str) -> bool:
return template.count("{") == template.count("}")
# assert braces_balanced(cfg["content"]) before loading Type guard
def is_balanced_template(content: str) -> bool:
return isinstance(content, str) and content.count("{") == content.count("}") Prevention
- Run a brace-count check on every prompt template before deploying.
- Avoid literal braces in prompt text, or double them if the renderer escapes.
- Keep placeholders on one line: {arg}, never split across lines.
When it happens
Trigger: Writing {symbol instead of {symbol}; including JSON examples with unescaped braces (e.g. {"key": "value"} where quotes confuse the count via one-sided braces); splitting a placeholder across lines; using single braces in text that needs them literal.
Common situations: Prompts embedding JSON/code samples with braces; typos in placeholders; copy-pasted markdown with stray '{' from formatting.
Related errors
- Prompt content cannot be empty
- Prompt name cannot be empty string
- Prompt name '{v}' should be a valid identifier
- Argument name cannot be empty
- Argument name '{v}' must be a valid Python identifier
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/5c4cf10535399ac3.
Report an issue: GitHub.