karpathy/nanochat · error · ValueError
Unknown part type: {part['type']}
Error message
Unknown part type: {part['type']} What it means
In `render_conversation`, an assistant message's content may be a list of typed parts. The supported part types are 'text', 'python' (a supervised tool call wrapped in <|python_start|>/<|python_end|>), and 'python_output' (unsupervised tool output wrapped in <|output_start|>/<|output_end|>). Any other value in part['type'] raises ValueError.
Source
Thrown at nanochat/tokenizer.py:216
elif isinstance(content, list):
for part in content:
value_ids = self.encode(part["text"])
if part["type"] == "text":
# string part => simply add the tokens
add_tokens(value_ids, 1)
elif part["type"] == "python":
# python tool call => add the tokens inside <|python_start|> and <|python_end|>
add_tokens(python_start, 1)
add_tokens(value_ids, 1)
add_tokens(python_end, 1)
elif part["type"] == "python_output":
# python output => add the tokens inside <|output_start|> and <|output_end|>
# none of these tokens are supervised because the tokens come from Python at test time
add_tokens(output_start, 0)
add_tokens(value_ids, 0)
add_tokens(output_end, 0)
else:
raise ValueError(f"Unknown part type: {part['type']}")
else:
raise ValueError(f"Unknown content type: {type(content)}")
add_tokens(assistant_end, 1)
# truncate to max_tokens tokens MAX (helps prevent OOMs)
ids = ids[:max_tokens]
mask = mask[:max_tokens]
return ids, mask
def visualize_tokenization(self, ids, mask, with_token_id=False):
"""Small helper function useful in debugging: visualize the tokenization of render_conversation"""
RED = '\033[91m'
GREEN = '\033[92m'
RESET = '\033[0m'
GRAY = '\033[90m'
tokens = []
for i, (token_id, mask_val) in enumerate(zip(ids, mask)):
token_str = self.decode([token_id])View on GitHub (pinned to 92d63d4e8b)
Solutions
- Map every assistant part to type 'text', 'python', or 'python_output' when preparing data.
- Convert OpenAI tool_calls entries: the call arguments become a 'python' part, the tool result becomes a 'python_output' part, plain prose becomes 'text'.
- Write a small pre-flight check over your dataset (see validation code) before training.
Example fix
# before
{"role": "assistant", "content": [{"type": "tool_call", "text": "2+2"}]}
# after
{"role": "assistant", "content": [{"type": "python", "text": "2+2"}]} Defensive patterns
Strategy: validation
Validate before calling
VALID_PART_TYPES = {'text', 'python', 'python_output'}
for msg in conversation["messages"]:
if isinstance(msg.get("content"), list):
for part in msg["content"]:
assert part.get("type") in VALID_PART_TYPES, f"bad part type {part.get('type')!r}" Type guard
def is_valid_part(part) -> bool:
return isinstance(part, dict) and part.get('type') in {'text', 'python', 'python_output'} and isinstance(part.get('text'), str) Prevention
- Map external chat formats (OpenAI tool_calls, ShareGPT) to nanochat part types at data-prep time.
- Validate a sample of conversations with render_conversation during dataset builds, before training.
- Use visualize_tokenization on a few rendered docs to eyeball the mapping.
When it happens
Trigger: Feeding a chat SFT dataset where assistant parts use other type labels — e.g. OpenAI-style 'tool_calls'/'function_call', 'tool_response', 'code', or a typo like 'pythonoutput' — into tokenizer.render_conversation.
Common situations: Converting external chat datasets (ShareGPT/OpenAI format) into nanochat's conversation format without mapping tool-call fields; hand-writing synthetic conversations with invented part types; dataset schema drift after an upstream update.
Related errors
- Unknown content type: {type(content)}
- Invalid input type: {type(text)}
- Unknown dataset tag: {dataset_tag}
- Unsupported task type: {task_type}
- '{formula}': timed out after {duration} seconds
AI-assisted analysis of karpathy/nanochat@92d63d4e8b (2026-08-15).
Data as JSON: /api/errors/a2abe98c17fc21ea.
Report an issue: GitHub.