{"record":{"id":"b627ffc1072e203a","repo":"sgl-project/sglang","slug":"no-call-message-found-for-call-id","errorCode":null,"errorMessage":"No call message found for {call_id}","messagePattern":"No call message found for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/entrypoints/harmony_utils.py","lineNumber":184,"sourceCode":"                c for c in content if c.get(\"type\") in (\"text\", \"input_text\")\n            ]\n            contents = [\n                TextContent(text=(text_prefix if i == 0 else \"\") + c.get(\"text\", \"\"))\n                for i, c in enumerate(text_chunks)\n            ]\n            msg = Message.from_role_and_contents(role, contents)\n    elif response_msg[\"type\"] == \"function_call_output\":\n        call_id = response_msg[\"call_id\"]\n        call_response: Optional[ResponseFunctionToolCall] = None\n        for prev_response in reversed(prev_responses):\n            if (\n                isinstance(prev_response, ResponseFunctionToolCall)\n                and prev_response.call_id == call_id\n            ):\n                call_response = prev_response\n                break\n        if call_response is None:\n            raise ValueError(f\"No call message found for {call_id}\")\n        msg = Message.from_author_and_content(\n            Author.new(Role.TOOL, f\"functions.{call_response.name}\"),\n            response_msg[\"output\"],\n        )\n    elif response_msg[\"type\"] == \"reasoning\":\n        content = response_msg[\"content\"]\n        assert len(content) == 1\n        msg = Message.from_role_and_content(Role.ASSISTANT, content[0][\"text\"])\n    elif response_msg[\"type\"] == \"function_call\":\n        msg = Message.from_role_and_content(Role.ASSISTANT, response_msg[\"arguments\"])\n        msg = msg.with_channel(\"commentary\")\n        msg = msg.with_recipient(f\"functions.{response_msg['name']}\")\n        msg = msg.with_content_type(\"json\")\n    else:\n        raise ValueError(f\"Unknown input type: {response_msg['type']}\")\n    return msg\n\n","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/entrypoints/harmony_utils.py#L166-L202","documentation":"In harmony_utils.parse_response_input, a 'function_call_output' response item references a call_id for which no matching ResponseFunctionToolCall exists in the prior context. The parser needs the paired call message (for the tool name) to build the harmony TOOL message, so an orphaned tool output is a hard error.","triggerScenarios":"Passing conversation history where an item with type 'function_call_output' has a call_id that doesn't match any earlier ResponseFunctionToolCall.call_id — dropped/truncated history, out-of-order items, or mismatched IDs from a client.","commonSituations":"Trimming old messages out of a long tool-use conversation and cutting the function_call but keeping its output; clients that regenerate call_ids; resuming sessions with truncated context windows.","solutions":["Ensure every function_call_output in the input history is preceded by its matching function_call item with the same call_id","If trimming history, drop each tool output together with its call","Regenerate the conversation from the source of truth (the original Responses API items) instead of hand-editing IDs"],"exampleFix":"# before\ninput = [{\"type\":\"function_call_output\",\"call_id\":\"call_1\",\"output\":\"42\"}]\n# after\ninput = [\n  {\"type\":\"function_call\",\"call_id\":\"call_1\",\"name\":\"get_x\",\"arguments\":\"{}\"},\n  {\"type\":\"function_call_output\",\"call_id\":\"call_1\",\"output\":\"42\"},\n]","handlingStrategy":"validation","validationCode":"def tool_outputs_are_paired(items):\n    call_ids = {i.get(\"call_id\") for i in items if i.get(\"type\") == \"function_call\"}\n    return all(i.get(\"call_id\") in call_ids\n               for i in items if i.get(\"type\") == \"function_call_output\")","typeGuard":"def has_matching_call(items, output_item) -> bool:\n    return any(\n        i.get(\"type\") == \"function_call\" and i.get(\"call_id\") == output_item.get(\"call_id\")\n        for i in items\n    )","tryCatchPattern":"try:\n    msgs = _construct_input_messages_with_harmony(items)\nexcept ValueError as e:\n    if \"No call message found\" in str(e):\n        items = [i for i in items if not (i.get(\"type\") == \"function_call_output\" and not has_matching_call(items, i))]\n        msgs = _construct_input_messages_with_harmony(items)\n    else:\n        raise","preventionTips":["Always keep function_call and function_call_output items paired when trimming history","Store original Responses API items verbatim instead of reconstructing them"],"tags":["harmony","tool-calls","conversation-history","validation","sglang"],"backgroundTag":"unmatched-tool-call-id","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}