{"record":{"id":"8b7d4e7382e7b6e8","repo":"sgl-project/sglang","slug":"inkling-thinking-part-payload-must-be-a-string","errorCode":null,"errorMessage":"Inkling thinking part payload must be a string","messagePattern":"Inkling thinking part payload must be a string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/parser/inkling_renderer.py","lineNumber":240,"sourceCode":"        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:\n            yield (\"image\", \"\")\n        elif ptype in _AUDIO_PART_TYPES:\n            yield (\"audio\", \"\")\n        else:\n            raise ValueError(f\"unsupported content part type: {ptype!r}\")\n\n\ndef _format_reasoning_effort(reasoning_effort: float) -> str:\n    if isinstance(reasoning_effort, bool) or not isinstance(\n        reasoning_effort, (int, float)\n    ):\n        raise TypeError(\"Inkling reasoning_effort must be a number\")\n    value = float(reasoning_effort)\n    if not math.isfinite(value) or not 0.0 <= value <= 0.99:\n        raise ValueError(\"Inkling reasoning_effort must be finite and in [0.0, 0.99]\")\n    return f\"{round(value, 2):g}\"","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/parser/inkling_renderer.py#L222-L258","documentation":"For parts with type 'thinking' or 'reasoning', the payload is read from part['thinking'] (falling back to part['text']) and must be a string. A dict, number, list, or None-with-non-string-fallback raises TypeError.","triggerScenarios":"Sending {\"type\":\"thinking\",\"thinking\":{\"steps\":[...]}} or {\"type\":\"reasoning\",\"text\":123}.","commonSituations":"Structured reasoning traces (step lists, JSON objects) placed directly into the thinking field.","solutions":["Serialize the thinking payload to a string (json.dumps / join)","Ensure either 'thinking' or 'text' key holds a str"],"exampleFix":"# before\n{\"type\":\"thinking\",\"thinking\":{\"steps\":[\"a\"]}}\n# after\n{\"type\":\"thinking\",\"thinking\":\"a\"}  # or json.dumps of the trace","handlingStrategy":"type-guard","validationCode":"for m in messages:\n    for p in (m.get(\"content\") or []) if isinstance(m.get(\"content\"), list) else []:\n        if isinstance(p, dict) and p.get(\"type\") in (\"thinking\",\"reasoning\"):\n            t = p.get(\"thinking\", p.get(\"text\"))\n            assert t is None or isinstance(t, str), type(t)","typeGuard":"def thinking_payload_ok(p):\n    if p.get(\"type\") not in (\"thinking\",\"reasoning\"): return True\n    t = p.get(\"thinking\") if p.get(\"thinking\") is not None else p.get(\"text\", \"\")\n    return isinstance(t, str)","tryCatchPattern":null,"preventionTips":["Always stringify thinking payloads (json.dumps for traces)"],"tags":["inkling","thinking","type-error"],"backgroundTag":"invalid-field-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}