{"record":{"id":"6c10261590b2a923","repo":"langchain-ai/langchain","slug":"invalid-format-specifier-in-f-string-template-nes","errorCode":null,"errorMessage":"Invalid format specifier in f-string template. Nested replacement fields are not allowed.","messagePattern":"Invalid format specifier in f-string template\\. Nested replacement fields are not allowed\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/prompts/string.py","lineNumber":255,"sourceCode":"                f\"Variable names cannot contain attribute \"\n                f\"access (.) or indexing ([]).\"\n            )\n            raise ValueError(msg)\n\n        if var.isdigit():\n            msg = (\n                f\"Invalid variable name {var!r} in f-string template. \"\n                f\"Variable names cannot be all digits as they are interpreted \"\n                f\"as positional arguments.\"\n            )\n            raise ValueError(msg)\n\n        if format_spec and (\"{\" in format_spec or \"}\" in format_spec):\n            msg = (\n                \"Invalid format specifier in f-string template. \"\n                \"Nested replacement fields are not allowed.\"\n            )\n            raise ValueError(msg)\n\n        input_variables.add(var)\n\n    return sorted(input_variables)\n\n\ndef check_valid_template(\n    template: str, template_format: str, input_variables: list[str]\n) -> None:\n    \"\"\"Check that template string is valid.\n\n    Args:\n        template: The template string.\n        template_format: The template format.\n\n            Should be one of `'f-string'` or `'jinja2'`.\n        input_variables: The input variables.\n","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/prompts/string.py#L237-L273","documentation":"Raised by `validate_f_string_template` when a replacement field's format specifier itself contains braces, e.g. `{value:>{width}}`. Nested replacement fields are legal in raw Python f-strings but LangChain's template formatting does not support them, so validation rejects the template with `ValueError` before any render attempt.","triggerScenarios":"A template like `\"{price:>{width}.2f}\"` or `{num:{fill}<{width}}` used with the default f-string `template_format`. The check `format_spec and (\"{\" in format_spec or \"}\" in format_spec)` trips as soon as the field is parsed.","commonSituations":"Porting display/alignment code that uses dynamic widths into prompt templates; attempting table-style padding inside prompts; copy-pasting f-strings from Python formatting guides.","solutions":["Hard-code the width in the format spec: `{price:>10.2f}`","Compute the padded string in Python before formatting the prompt: `padded = f\"{price:>{width}.2f}\"` then use `{padded}` in the template","For loop-driven dynamic layout, render the whole fragment with `template_format=\"jinja2\"` and Jinja2 filters (requires jinja2 installed)"],"exampleFix":"# before\nprompt = PromptTemplate.from_template(\"total: {price:>{width}.2f}\")\n\n# after\npadded_total = f\"{price:>{width}.2f}\"\nprompt = PromptTemplate.from_template(\"total: {padded_total}\")\nprompt.format(padded_total=padded_total)","handlingStrategy":"validation","validationCode":"import re\n\ndef has_no_nested_format_spec(template: str) -> bool:\n    for spec in re.findall(r\"\\{[^{}]+:([^{}]*)\\}\", template):\n        if \"{\" in spec or \"}\" in spec:\n            return False\n    return True\n\nassert has_no_nested_format_spec(template)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep dynamic layout (widths, padding) in Python code, not in the template spec","Hard-code widths in format specs: {price:>10.2f}","Use jinja2 filters for dynamic alignment if truly needed"],"tags":["prompts","f-string","format-spec","template-validation","valueerror"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}