hiyouga/LlamaFactory · error · ValueError

Dict is not supported.

Error message

Dict is not supported.

What it means

When exporting a chat template to Jinja2 format (_convert_slots_to_jinja, used by get_template_and_fix_tokenizer / saving chat templates), slot elements of dict type cannot be represented because Jinja conversion only understands strings, {{placeholder}} slots, and set-type bos/eos tokens. Encountering a {'token': ...} dict slot raises ValueError('Dict is not supported.').

Source

Thrown at src/llamafactory/data/template.py:241

    def _convert_slots_to_jinja(slots: "SLOTS", tokenizer: "PreTrainedTokenizer", placeholder: str = "content") -> str:
        r"""Convert slots to jinja template."""
        slot_items = []
        for slot in slots:
            if isinstance(slot, str):
                slot_pieces = slot.split("{{content}}")
                if slot_pieces[0]:
                    slot_items.append("'" + Template._jinja_escape(slot_pieces[0]) + "'")
                if len(slot_pieces) > 1:
                    slot_items.append(placeholder)
                    if slot_pieces[1]:
                        slot_items.append("'" + Template._jinja_escape(slot_pieces[1]) + "'")
            elif isinstance(slot, set):  # do not use {{ eos_token }} since it may be replaced
                if "bos_token" in slot and tokenizer.bos_token_id is not None:
                    slot_items.append("'" + tokenizer.bos_token + "'")
                elif "eos_token" in slot and tokenizer.eos_token_id is not None:
                    slot_items.append("'" + tokenizer.eos_token + "'")
            elif isinstance(slot, dict):
                raise ValueError("Dict is not supported.")

        return " + ".join(slot_items)

    def _get_jinja_template(self, tokenizer: "PreTrainedTokenizer") -> str:
        r"""Return the jinja template."""
        prefix = self._convert_slots_to_jinja(self.format_prefix.apply(), tokenizer)
        system = self._convert_slots_to_jinja(self.format_system.apply(), tokenizer, placeholder="system_message")
        user = self._convert_slots_to_jinja(self.format_user.apply(), tokenizer)
        assistant = self._convert_slots_to_jinja(self.format_assistant.apply(), tokenizer)
        jinja_template = ""
        if prefix:
            jinja_template += "{{ " + prefix + " }}"

        if self.default_system:
            jinja_template += "{% set system_message = '" + self._jinja_escape(self.default_system) + "' %}"

        jinja_template += (
            "{% if messages[0]['role'] == 'system' %}{% set loop_messages = messages[1:] %}"

View on GitHub (pinned to f28afaf635)

Solutions

  1. Replace dict slots with plain string literals of the exact token text (e.g. "<|sep|>") so the Jinja template embeds it verbatim.
  2. Or use the set form {"eos_token"}/{"bos_token"} which the converter translates to the tokenizer's special tokens.
  3. Avoid paths that materialize the Jinja template for the custom template, or patch _convert_slots_to_jinja to handle dict tokens.

Example fix

# before
format_user=StringFormatter(slots=["<user>{{content}}", {"token": "<|sep|>"}])

# after
format_user=StringFormatter(slots=["<user>{{content}}<|sep|>"])
Defensive patterns

Strategy: validation

Validate before calling

def template_jinja_exportable(template) -> bool:
    for fmt in (template.format_user, template.format_assistant, template.format_prefix, template.format_system):
        if any(isinstance(s, dict) for s in (fmt.slots or [])):
            return False
    return True

Prevention

When it happens

Trigger: Calling template._get_jinja_template(tokenizer) (or an export/API path that materializes the Jinja chat template) on a template whose formatter slots contain a {"token": ...} entry, such as templates that reference tokens by name rather than via the eos_token set.

Common situations: Registering a custom template with {"token": "<|sep|>"} slots and then serving it via the OpenAI-style API or exporting the chat template; version upgrades that started building Jinja templates for API serving.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/21374722396cffa9. Report an issue: GitHub.