langchain-ai/langchain · error · ValueError
Invalid variable name {var!r} in f-string template. Variable
Error message
Invalid variable name {var!r} in f-string template. Variable names cannot be all digits as they are interpreted as positional arguments. What it means
Raised by `validate_f_string_template` when an f-string template's variable name consists only of digits, e.g. `{0}` or `{1}`. In Python's format protocol such fields are positional arguments, but LangChain invokes formatting with keyword arguments derived from `input_variables`, so purely numeric names are unusable and rejected with `ValueError`.
Source
Thrown at libs/core/langchain_core/prompts/string.py:248
def validate_f_string_template(template: str) -> list[str]:
"""Validate an f-string template and return its input variables."""
input_variables = set()
for var, format_spec in _parse_f_string_fields(template):
if "." in var or "[" in var or "]" in var:
msg = (
f"Invalid variable name {var!r} in f-string template. "
f"Variable names cannot contain attribute "
f"access (.) or indexing ([])."
)
raise ValueError(msg)
if var.isdigit():
msg = (
f"Invalid variable name {var!r} in f-string template. "
f"Variable names cannot be all digits as they are interpreted "
f"as positional arguments."
)
raise ValueError(msg)
if format_spec and ("{" in format_spec or "}" in format_spec):
msg = (
"Invalid format specifier in f-string template. "
"Nested replacement fields are not allowed."
)
raise ValueError(msg)
input_variables.add(var)
return sorted(input_variables)
def check_valid_template(
template: str, template_format: str, input_variables: list[str]
) -> None:
"""Check that template string is valid.
View on GitHub (pinned to e32fa9a52e)
Solutions
- Rename the placeholders to descriptive identifiers: `"{speaker} said: {utterance}"`, and pass those names as format kwargs
- If the values genuinely come from a list, unpack them into named locals first (`speaker, utterance = rows[0]`) and format with names
- If positional formatting must be preserved, format the string yourself before constructing the template
Example fix
# before
prompt = PromptTemplate.from_template("{0}: {1}")
# after
prompt = PromptTemplate.from_template("{speaker}: {utterance}")
prompt.format(speaker="Ada", utterance="hello") Defensive patterns
Strategy: validation
Validate before calling
import re
def has_no_numeric_vars(template: str) -> bool:
return not any(v.isdigit() for v in re.findall(r"\{(\w+)\}", template))
assert has_no_numeric_vars(template) Prevention
- Always name placeholders descriptively in prompt templates
- Auto-generate templates with named fields, never positional indices
- Convert `{0}`-style strings to `{name}` before passing to from_template
When it happens
Trigger: A template like `"{0} said: {1}"` passed to `PromptTemplate.from_template(...)` (default f-string format), or to `validate_f_string_template` / `get_template_variables(..., "f-string")`. The `var.isdigit()` check fires for each parsed field.
Common situations: Translating `str.format`-style code or `.format(*args)` call sites into prompt templates; auto-generated templates that number placeholders; templates converted from CSV/JSON resources that use positional markers.
Related errors
- Invalid variable name {var!r} in f-string template. Variable
- Invalid format specifier in f-string template. Nested replac
- Invalid prompt schema; check for mismatched or missing input
- Saving an example selector is not currently supported
- Loading {config_type} prompt not supported
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/827451cfd272b533.
Report an issue: GitHub.