{"record":{"id":"5c4cf10535399ac3","repo":"OpenBB-finance/OpenBB","slug":"unmatched-braces-in-prompt-content-open-braces","errorCode":null,"errorMessage":"Unmatched braces in prompt content: {open_braces} opening, {close_braces} closing","messagePattern":"Unmatched braces in prompt content: (.+?) opening, (.+?) closing","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/extensions/mcp_server/openbb_mcp_server/models/mcp_config.py","lineNumber":112,"sourceCode":"    arguments: list[ArgumentDefinitionModel] = Field(\n        default_factory=list, description=\"Argument definitions for the prompt\"\n    )\n    tags: list[str] = Field(\n        default_factory=list, description=\"Tags for categorizing the prompt\"\n    )\n\n    @field_validator(\"content\")\n    @classmethod\n    def validate_content(cls, v: str) -> str:\n        \"\"\"Validate content is not empty and contains valid template syntax.\"\"\"\n        if not v.strip():\n            raise ValueError(\"Prompt content cannot be empty\")\n\n        # Check for unmatched braces\n        open_braces = v.count(\"{\")\n        close_braces = v.count(\"}\")\n        if open_braces != close_braces:\n            raise ValueError(\n                f\"Unmatched braces in prompt content: {open_braces} opening, {close_braces} closing\"\n            )\n\n        return v\n\n    @field_validator(\"name\")\n    @classmethod\n    def validate_name(cls, v: str | None) -> str | None:\n        \"\"\"Validate prompt name if provided.\"\"\"\n        if v is not None:\n            if not v.strip():\n                raise ValueError(\"Prompt name cannot be empty string\")\n            # Check for valid identifier-like name\n            if not re.match(r\"^[a-zA-Z_][a-zA-Z0-9_]*$\", v.strip()):\n                raise ValueError(f\"Prompt name '{v}' should be a valid identifier\")\n        return v\n\n    @field_validator(\"tags\")","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/extensions/mcp_server/openbb_mcp_server/models/mcp_config.py#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"Prompts embedding JSON/code samples with braces; typos in placeholders; copy-pasted markdown with stray '{' from formatting.","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."],"exampleFix":"# before\ncontent: \"Fetch data for {symbol and return JSON\"\n\n# after\ncontent: \"Fetch data for {symbol} and return JSON\"","handlingStrategy":"validation","validationCode":"def braces_balanced(template: str) -> bool:\n    return template.count(\"{\") == template.count(\"}\")\n\n# assert braces_balanced(cfg[\"content\"]) before loading","typeGuard":"def is_balanced_template(content: str) -> bool:\n    return isinstance(content, str) and content.count(\"{\") == content.count(\"}\")","tryCatchPattern":null,"preventionTips":["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."],"tags":["openbb","mcp","pydantic","prompts","templating"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}