{"record":{"id":"542ef28fc213569d","repo":"sgl-project/sglang","slug":"message-content-must-be-a-string-or-a-sequence-of","errorCode":null,"errorMessage":"message content must be a string or a sequence of parts","messagePattern":"message content must be a string or a sequence of parts","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/parser/inkling_renderer.py","lineNumber":224,"sourceCode":"    elif kind == \"invoke_tool_json\":\n        input_ids.append(tokenizer.encode_special(CONTENT_INVOKE_TOOL_JSON))\n        input_ids.extend(tokenizer.encode_text(text))\n    else:\n        raise ValueError(f\"unsupported Inkling render part kind: {kind!r}\")\n\n    input_ids.append(tokenizer.encode_special(END_MESSAGE))\n\n\ndef _iter_render_parts(content: Any):\n    \"\"\"Yield ordered ``(kind, text)`` pairs from message content.\"\"\"\n    if content is None:\n        return\n    if isinstance(content, str):\n        if content:\n            yield (\"text\", content)\n        return\n    if not isinstance(content, Sequence) or isinstance(content, (bytes, bytearray)):\n        raise TypeError(\"message content must be a string or a sequence of parts\")\n    for part in content:\n        if isinstance(part, str):\n            yield (\"text\", part)\n            continue\n        if not isinstance(part, Mapping):\n            raise TypeError(f\"content part must be mapping, got {type(part).__name__}\")\n        ptype = part.get(\"type\")\n        if ptype in (None, \"text\", \"input_text\"):\n            text = part.get(\"text\", \"\")\n            yield (\"text\", text if isinstance(text, str) else \"\")\n        elif ptype in (\"thinking\", \"reasoning\"):\n            text = part.get(\"thinking\")\n            if text is None:\n                text = part.get(\"text\", \"\")\n            if not isinstance(text, str):\n                raise TypeError(\"Inkling thinking part payload must be a string\")\n            yield (\"thinking\", text)\n        elif ptype in _IMAGE_PART_TYPES:","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/parser/inkling_renderer.py#L206-L242","documentation":"_iter_render_parts accepts message content that is either a string or a non-bytes Sequence of parts. Passing bytes/bytearray, a dict, a number, or None-like non-string scalar raises TypeError.","triggerScenarios":"Passing message.content as bytes (e.g. a JSON-encoded payload not decoded), a dict, or an int in an Inkling-rendered chat request.","commonSituations":"Programmatic clients that forget json.loads on serialized messages, or that pass a single mapping as content instead of a list of mappings.","solutions":["Decode bytes to str and json.loads if it is a serialized message list","Pass content as a string or a list of part dicts","Wrap a single part dict in a list"],"exampleFix":"# before\nmsg[\"content\"] = b'[{\"type\":\"text\",\"text\":\"hi\"}]'\n# after\nmsg[\"content\"] = json.loads(msg[\"content\"].decode())  # or just \"hi\"","handlingStrategy":"type-guard","validationCode":"from collections.abc import Sequence, Mapping, ByteString\nfor m in messages:\n    c = m.get(\"content\", \"\")\n    assert isinstance(c, str) or (isinstance(c, Sequence) and not isinstance(c, ByteString)), type(c)","typeGuard":"def content_ok(c):\n    return isinstance(c, str) or (isinstance(c, Sequence) and not isinstance(c, (bytes, bytearray)))","tryCatchPattern":null,"preventionTips":["json.loads serialized payloads before sending","Never pass bytes content"],"tags":["inkling","type-error","content"],"backgroundTag":"invalid-field-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}