meta-llama/llama · error

Error: special tags are not allowed as part of the prompt.

Error message

Error: special tags are not allowed as part of the prompt.

What it means

This is the UNSAFE_ERROR assertion in Llama.chat_completion (llama/generation.py). It fires when any message content in the dialog already contains one of the model's reserved control tags: '[INST]', '[/INST]', '<<SYS>>', or '<</SYS>>'. The library itself wraps user prompts and system messages with these tags when building the token sequence, so pre-existing tags would let the prompt inject fake instructions or system blocks, and the guard refuses to build such a prompt.

Source

Thrown at llama/generation.py:48

class CompletionPrediction(TypedDict, total=False):
    generation: str
    tokens: List[str]  # not required
    logprobs: List[float]  # not required


class ChatPrediction(TypedDict, total=False):
    generation: Message
    tokens: List[str]  # not required
    logprobs: List[float]  # not required


Dialog = List[Message]

B_INST, E_INST = "[INST]", "[/INST]"
B_SYS, E_SYS = "<<SYS>>\n", "\n<</SYS>>\n\n"

SPECIAL_TAGS = [B_INST, E_INST, "<<SYS>>", "<</SYS>>"]
UNSAFE_ERROR = "Error: special tags are not allowed as part of the prompt."


class Llama:
    @staticmethod
    def build(
        ckpt_dir: str,
        tokenizer_path: str,
        max_seq_len: int,
        max_batch_size: int,
        model_parallel_size: Optional[int] = None,
        seed: int = 1,
    ) -> "Llama":
        """
        Build a Llama instance by initializing and loading a pre-trained model.

        Args:
            ckpt_dir (str): Path to the directory containing checkpoint files.
            tokenizer_path (str): Path to the tokenizer file.

View on GitHub (pinned to 689c7f261b)

Solutions

  1. Strip or escape the special tags from every message's content before calling chat_completion (e.g. replace '[INST]'/'[/INST]'/'<<SYS>>'/'<</SYS>>' with inert variants like '\[INST\]')
  2. If your data is pre-templated '[INST] ... [/INST]' text, remove the tags and pass only the inner text as user/assistant messages — the library adds tags itself
  3. If you truly need raw control over the token stream, bypass chat_completion and call llama.generate with tokenizer.encode output you build yourself
  4. Sanitize at ingestion: validate stored conversation data once at load time rather than at every request

Example fix

# before
dialog = [{"role": "user", "content": "[INST] tell me a joke [/INST]"}]
llama.chat_completion([dialog], max_gen_len=64)

# after
SPECIAL = ("[INST]", "[/INST]", "<<SYS>>", "<</SYS>>")
def sanitize(text):
    for tag in SPECIAL:
        text = text.replace(tag, tag.replace("[", "[").replace("]", "]"))
    return text
dialog = [{"role": "user", "content": sanitize("[INST] tell me a joke [/INST]")}]
llama.chat_completion([dialog], max_gen_len=64)
Defensive patterns

Strategy: validation

Validate before calling

SPECIAL_TAGS = ("[INST]", "[/INST]", "<<SYS>>", "<</SYS>>")

def prompt_is_safe(dialog):
    return not any(tag in m["content"] for tag in SPECIAL_TAGS for m in dialog)

# before calling:
assert prompt_is_safe(dialog), "dialog contains reserved Llama tags"

Type guard

from typing import List, Dict

def is_safe_dialog(dialog: List[Dict[str, str]]) -> bool:
    return (
        isinstance(dialog, list)
        and all(isinstance(m, dict) and isinstance(m.get("content"), str) for m in dialog)
        and not any(t in m["content"] for t in SPECIAL_TAGS for m in dialog)
    )

Try / catch

try:
    result = llama.chat_completion([dialog], max_gen_len=128)
except AssertionError as e:
    if "special tags" in str(e):
        dialog = [{"role": m["role"], "content": sanitize(m["content"])} for m in dialog]
        result = llama.chat_completion([dialog], max_gen_len=128)
    else:
        raise

Prevention

When it happens

Trigger: Calling llama.chat_completion(dialogs, ...) where any dialog message's 'content' string includes '[INST]', '[/INST]', '<<SYS>>', or '<</SYS>>' (the check is `any(tag in msg['content'] for tag in SPECIAL_TAGS for msg in dialog)`). Typical case: a chat UI that echoes a prior raw Llama-formatted prompt, or a dataset of pre-templated '[INST] ... [/INST]' examples fed directly as message content.

Common situations: - Feeding already-rendered Llama 2 chat prompts (from logs or sharegpt-style datasets) as message content instead of plain text. - Round-tripping model output back as input: an assistant reply that quotes the tags is fine, but a user message pasting them (e.g. documenting the format) trips it. - Prompt-injection-hardened frontends testing the boundary, or multi-turn pipelines where the system prompt was stored with its '<<SYS>>' wrappers.

Related errors


AI-assisted analysis of meta-llama/llama@689c7f261b (2026-08-15). Data as JSON: /api/errors/738ac7fb3d8cb7f3. Report an issue: GitHub.