hiyouga/LlamaFactory · error · ValueError
Empty formatter should not contain any placeholder.
Error message
Empty formatter should not contain any placeholder.
What it means
EmptyFormatter is meant to be a constant slot list (e.g. an empty user prompt or a fixed eos token). Its __post_init__ scans string slots for the {{placeholder}} regex and raises ValueError if any is found — placeholders make no sense in a formatter whose apply() ignores kwargs and returns slots verbatim.
Source
Thrown at src/llamafactory/data/formatter.py:53
def extract(self, content: str) -> str | list["FunctionCall"]:
r"""Extract a list of tuples from the response message if using tools.
Each tuple consists of function name and function arguments.
"""
raise NotImplementedError
@dataclass
class EmptyFormatter(Formatter):
def __post_init__(self):
has_placeholder = False
for slot in filter(lambda s: isinstance(s, str), self.slots):
if re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", slot):
has_placeholder = True
if has_placeholder:
raise ValueError("Empty formatter should not contain any placeholder.")
@override
def apply(self, **kwargs) -> SLOTS:
return self.slots
@dataclass
class StringFormatter(Formatter):
def __post_init__(self):
has_placeholder = False
for slot in filter(lambda s: isinstance(s, str), self.slots):
if re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", slot):
has_placeholder = True
if not has_placeholder:
raise ValueError("A placeholder is required in the string formatter.")
@overrideView on GitHub (pinned to f28afaf635)
Solutions
- Remove the {{...}} placeholder from the EmptyFormatter slots, or
- Switch to StringFormatter (or a subclass) if the slot genuinely needs substitution.
Example fix
# before
EmptyFormatter(slots=["Answer: {{response}}"])
# after
StringFormatter(slots=["Answer: {{response}}"]) Defensive patterns
Strategy: validation
Validate before calling
import re
ph = any(re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", s) for s in slots if isinstance(s, str))
if ph:
assert formatter_cls is not EmptyFormatter, "EmptyFormatter cannot hold placeholders — use StringFormatter" Prevention
- When authoring custom templates, choose formatter by 'does this slot substitute data?'.
- Unit-test custom templates: instantiate all formters in __post_init__ during CI.
When it happens
Trigger: Defining a custom template whose element uses EmptyFormatter but the slot text contains something like {{query}} or {{system}}; usually a copy-paste from a StringFormatter-based template where the placeholder was left behind.
Common situations: Writing/registering a custom template and mistaking which formatter class to use; refactoring a template and switching StringFormatter to EmptyFormatter without removing the placeholder.
Related errors
- A placeholder is required in the string formatter.
- Expected a string, got {value}
- This model does not support image input. Please check whethe
- This model does not support video input. Please check whethe
- This model does not support audio input. Please check whethe
AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14).
Data as JSON: /api/errors/42a3d41bf8f6c5c9.
Report an issue: GitHub.