{"record":{"id":"80bff17fed5e05a8","repo":"sgl-project/sglang","slug":"assistant-message-cannot-mix-reasoning-content-wit","errorCode":null,"errorMessage":"assistant message cannot mix reasoning_content with ordered thinking parts","messagePattern":"assistant message cannot mix reasoning_content with ordered thinking parts","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/parser/inkling_renderer.py","lineNumber":134,"sourceCode":"                    tokenizer,\n                    \"tool\",\n                    kind,\n                    text,\n                    author_name=tool_name,\n                )\n            continue\n\n        parts = list(_iter_render_parts(message.get(\"content\", \"\")))\n        turn_start = len(input_ids)\n        if role == \"assistant\":\n            reasoning_content = message.get(\"reasoning_content\")\n            if reasoning_content:\n                if not isinstance(reasoning_content, str):\n                    raise TypeError(\n                        \"assistant reasoning_content must be a string for Inkling rendering\"\n                    )\n                if any(kind == \"thinking\" for kind, _ in parts):\n                    raise ValueError(\n                        \"assistant message cannot mix reasoning_content with ordered thinking parts\"\n                    )\n                _append_message(\n                    input_ids,\n                    tokenizer,\n                    \"assistant\",\n                    \"thinking\",\n                    reasoning_content,\n                )\n\n        for kind, text in parts:\n            if kind == \"thinking\" and role != \"assistant\":\n                raise ValueError(\"Inkling thinking parts require role='assistant'\")\n            _append_message(input_ids, tokenizer, role, kind, text)\n\n        if role == \"assistant\":\n            for tool_call in message.get(\"tool_calls\") or []:\n                name, args = _tool_call_name_and_args(tool_call)","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/parser/inkling_renderer.py#L116-L152","documentation":"An assistant message may carry reasoning through either the top-level reasoning_content string OR ordered 'thinking' content parts, but not both — combining them would duplicate reasoning in the rendered transcript. If both are present, the renderer raises ValueError.","triggerScenarios":"Sending {\"role\":\"assistant\",\"reasoning_content\":\"...\",\"content\":[{\"type\":\"thinking\",\"thinking\":\"...\"}, ...]} in conversation history.","commonSituations":"Clients that merge model output back into both fields when recording multi-turn conversations.","solutions":["Keep reasoning in exactly one place: either reasoning_content or thinking parts","Strip reasoning_content when the assistant message content already includes thinking parts"],"exampleFix":"# before\n{\"role\":\"assistant\",\"reasoning_content\":\"think...\",\"content\":[{\"type\":\"thinking\",\"thinking\":\"think...\"},{\"type\":\"text\",\"text\":\"ans\"}]}\n# after\n{\"role\":\"assistant\",\"content\":[{\"type\":\"thinking\",\"thinking\":\"think...\"},{\"type\":\"text\",\"text\":\"ans\"}]}","handlingStrategy":"validation","validationCode":"for m in messages:\n    if m.get(\"reasoning_content\") and isinstance(m.get(\"content\"), list):\n        assert not any(isinstance(p, dict) and p.get(\"type\") in (\"thinking\",\"reasoning\") for p in m[\"content\"])","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one canonical field for reasoning in stored transcripts","Strip reasoning_content when content already has thinking parts"],"tags":["inkling","reasoning","conflicting-fields"],"backgroundTag":"conflicting-request-fields","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}