Click any words you think contain an error. Click again to unmark.
Gluing role labels to content with no spaces flips the boundary tokens to their no leading space variants, so the model sees off-distribution IDs; use apply_chat_template instead.
Imagine writing a play script where you forget to put a space between the character's name and their line, so it reads 'NARRATORonce upon a time'. A reader can sort of guess, but it looks wrong and they stumble. A tokenizer stumbles the same way. When you paste 'system:' straight onto the actual prompt with no gap, the first word of the prompt becomes a strange smushed-together piece the model rarely saw while learning. The fix is simple: add the spaces, or better, let the library format the chat for you.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
This snippet is the kind of code that ships because it looks obviously fine. The string is human-readable, the model returns sensible answers, and tests pass. Yet it carries a real tokenization defect, and a senior candidate is expected to find not just the surface mistake but the deeper architectural one beneath it.
The surface mistake is the missing spaces at the role boundaries. The deeper mistake is hand-assembling a chat prompt at all. We will work through why a dropped space changes token IDs, why that matters most at exactly these boundaries, why patching the spaces is only half a fix, and what the correct production pattern is. The throughline is that prompt formatting is coupled to the tokenizer and the model, and pretending otherwise is where the bug lives.
Locating the two errors
Read the concatenation carefully. The first piece is 'system:' + system_prompt. With no trailing space on the label, the first word of system_prompt is glued directly to the colon, producing text like system:Hello. The second piece is 'user:' + user_msg, which glues the first word of user_msg onto user: the same way.
That is two boundary errors, not one. A common partial answer spots only the more visually jarring of the two and stops. The corrections restore a space on each side: a space after the system colon so the prompt starts cleanly, and a leading space before user: so its word boundary is preserved too.
Why does a space change anything at all? Because of what a token is in this tokenizer, which the next section covers.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
# Buggy: role labels glued to content, two broken boundaries
prompt = "system:" + system_prompt + "user:" + user_msg
tokens = tokenizer.encode(prompt) # first content word loses its leading-space token
# Local patch: restore boundary spaces
prompt = "system: " + system_prompt + " user:" + user_msg
# Real fix: let the model's own template format the chat
msgs = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_msg},
]
tokens = tokenizer.apply_chat_template(msgs, add_generation_prompt=True)Real products, models, and research that use this idea.
- HuggingFace's apply_chat_template() exists precisely to stop this bug, applying each model's Jinja template with correct spacing and special tokens for Llama 4, Mistral Large 3, and Qwen 3.5.
- Early LangChain and llama.cpp users hit garbled outputs from hand-concatenated role strings before chat-template support became standard.
What an interviewer would ask next. Try answering before peeking at the approach.
QEven with the spaces added, why is this prompt still wrong for a real chat model?
Bare 'system:' is not the model's actual turn format; it needs model-specific special tokens and delimiters from the chat template, not human-readable labels.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Assuming string concatenation is tokenizer-neutral, so 'system:' + prompt tokenizes the same as 'system: ' + prompt.
60 second bullets to scan on the way to the call.
How many boundary errors are in the snippet
Why a missing space changes the first content token's ID
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.