unslothai/unsloth · error · ValueError
Chat template exceeds the {MAX_CHAT_TEMPLATE_BYTES}-byte lim
Error message
Chat template exceeds the {MAX_CHAT_TEMPLATE_BYTES}-byte limit. What it means
Field validator on ValidateChatTemplateRequest.template enforcing a hard byte-size cap (MAX_CHAT_TEMPLATE_BYTES) on the chat template. The size is computed as the UTF-8 byte length (chat_template_byte_length), not character count, so templates with many multi-byte characters hit the limit sooner. Oversized templates are rejected because they bloat every tokenizer config request and can exceed downstream storage/transfer limits.
Source
Thrown at studio/backend/picker/schemas.py:37
"reject": such a template can never render.
"""
try:
return len(value.encode("utf-8"))
except UnicodeEncodeError:
return None
class ValidateChatTemplateRequest(BaseModel):
template: str = Field(default = "")
@field_validator("template")
@classmethod
def _enforce_template_size(cls, value: str) -> str:
size = chat_template_byte_length(value)
if size is None:
raise ValueError("Chat template contains unpaired surrogate characters.")
if size > MAX_CHAT_TEMPLATE_BYTES:
raise ValueError(f"Chat template exceeds the {MAX_CHAT_TEMPLATE_BYTES}-byte limit.")
return value
class ValidateChatTemplateResponse(BaseModel):
valid: bool
error: Optional[str] = None
class ModelTemplateResponse(BaseModel):
model_name: str
chat_template: Optional[str] = None
View on GitHub (pinned to 203007d190)
Solutions
- Trim the template: move large few-shot examples or system text out of the template and pass them as message content at runtime instead.
- Reduce duplicated Jinja branches by using macros/loops over message roles.
- Verify the byte size locally before sending: len(template.encode('utf-8')) and keep it under the limit.
Example fix
# before
template = "{%- for shot in [LONG_FEW_SHOT_1, LONG_FEW_SHOT_2, ...] %}..." # > limit bytes
# after
# keep only structural Jinja in the template; inject few-shot text via messages at inference time
template = "{%- for message in messages %}{{ message.content }}{% endfor %}" Defensive patterns
Strategy: validation
Validate before calling
MAX_CHAT_TEMPLATE_BYTES = 65_536 # keep in sync with the server constant
def template_fits(template: str) -> bool:
try:
return len(template.encode("utf-8")) <= MAX_CHAT_TEMPLATE_BYTES
except UnicodeEncodeError:
return False # unpaired surrogates — see separate error Prevention
- Measure bytes, not characters: len(s.encode('utf-8')).
- Keep large prompt content out of the template; inject it via messages at runtime.
When it happens
Trigger: POSTing a ValidateChatTemplateRequest whose template's UTF-8 encoding exceeds MAX_CHAT_TEMPLATE_BYTES (e.g. a template with dozens of macro definitions or large embedded few-shot examples).
Common situations: Templates with long hardcoded system prompts or few-shot examples inlined; templates copied from another repo that include extensive branching for many message roles; non-ASCII (CJK/emoji) content roughly tripling byte count versus character count.
Related errors
- Chat template exceeds the {MAX_CHAT_TEMPLATE_BYTES}-byte lim
- Chat template exceeds the {MAX_CHAT_TEMPLATE_BYTES}-byte lim
- Chat template contains unpaired surrogate characters.
- Chat template contains unpaired surrogate characters.
- Image is too large ({w}x{h}); maximum is {max_side}px per si
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/bef6cfa934e98a37.
Report an issue: GitHub.