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
- 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\]')
- 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
- If you truly need raw control over the token stream, bypass chat_completion and call llama.generate with tokenizer.encode output you build yourself
- 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
- Sanitize all user-supplied text at ingestion: replace '[INST]', '[/INST]', '<<SYS>>', '<</SYS>>' with escaped variants
- Store conversations as plain role/content, never pre-rendered Llama templates
- Add a unit test asserting your chat pipeline rejects or escapes reserved tags before reaching the model
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
- model only supports 'system', 'user' and 'assistant' roles,
- Last message must be from user, got {dialog[-1]['role']}
- no checkpoint files found in {ckpt_dir}
- Loading a checkpoint for MP={len(checkpoints)} but world siz
AI-assisted analysis of meta-llama/llama@689c7f261b (2026-08-15).
Data as JSON: /api/errors/738ac7fb3d8cb7f3.
Report an issue: GitHub.