{"record":{"id":"f4b26e1f3800f5aa","repo":"huggingface/smolagents","slug":"no-content-or-tool-calls-in-event-event","errorCode":null,"errorMessage":"No content or tool calls in event: {event}","messagePattern":"No content or tool calls in event: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/smolagents/models.py","lineNumber":1360,"sourceCode":"                choice = event.choices[0]\n                if choice.delta:\n                    yield ChatMessageStreamDelta(\n                        content=choice.delta.content,\n                        tool_calls=[\n                            ChatMessageToolCallStreamDelta(\n                                index=delta.index,\n                                id=delta.id,\n                                type=delta.type,\n                                function=delta.function,\n                            )\n                            for delta in choice.delta.tool_calls\n                        ]\n                        if choice.delta.tool_calls\n                        else None,\n                    )\n                else:\n                    if not getattr(choice, \"finish_reason\", None):\n                        raise ValueError(f\"No content or tool calls in event: {event}\")\n\n\nclass LiteLLMRouterModel(LiteLLMModel):\n    \"\"\"Router‑based client for interacting with the [LiteLLM Python SDK Router](https://docs.litellm.ai/docs/routing).\n\n    This class provides a high-level interface for distributing requests among multiple language models using\n    the LiteLLM SDK's routing capabilities. It is responsible for initializing and configuring the router client,\n    applying custom role conversions, and managing message formatting to ensure seamless integration with various LLMs.\n\n    Parameters:\n        model_id (`str`):\n            Identifier for the model group to use from the model list (e.g., \"model-group-1\").\n        model_list (`list[dict[str, Any]]`):\n            Model configurations to be used for routing.\n            Each configuration should include the model group name and any necessary parameters.\n            For more details, refer to the [LiteLLM Routing](https://docs.litellm.ai/docs/routing#quick-start) documentation.\n        client_kwargs (`dict[str, Any]`, *optional*):\n            Additional configuration parameters for the Router client. For more details, see the","sourceCodeStart":1342,"sourceCodeEnd":1378,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/models.py#L1342-L1378","documentation":"During streaming generation, LiteLLMModel.generate_stream received a chunk whose choice delta has neither content, tool_calls, nor a finish_reason. smolagents raises ValueError because such an event carries nothing usable and (missing finish_reason) does not even signal a normal stream end. This usually indicates a malformed or unexpected SSE chunk from the provider/LiteLLM.","triggerScenarios":"Calling generate_stream (e.g. agent.run(stream=True)) with a provider whose stream chunks include empty deltas or non-standard events; role-only deltas at stream start handled incorrectly; provider sends keep-alive or usage-only chunks in an unexpected shape.","commonSituations":"Provider-specific streaming quirks (Bedrock, Gemini, Anthropic via LiteLLM); LiteLLM version mismatch changing chunk normalization; proxies stripping delta fields; interruptions mid-stream producing truncated chunks.","solutions":["Upgrade (or pin) litellm to the latest version — chunk normalization fixes land frequently.","Print/log the raw event shown in the message to identify which field is missing and from which provider it comes.","If the provider is known to emit ignorable chunks, test with a different provider to confirm it's provider-specific and report/patch the delta parsing in generate_stream.","Fall back to non-streaming generate() while investigating."],"exampleFix":"# before\nfor chunk in model.generate_stream(messages):  # ValueError: No content or tool calls in event\n    ...\n\n# after\nmsg = model.generate(messages)  # non-streaming path while provider chunk issue is investigated\nprint(msg.content)","handlingStrategy":"try-catch","validationCode":"import litellm\nstream = litellm.completion(model=model_id, messages=[{\"role\":\"user\",\"content\":\"ping\"}], stream=True)\nfor ev in stream:\n    delta = ev.choices[0].delta if ev.choices else None\n    if delta and not getattr(delta, \"content\", None) and not getattr(delta, \"tool_calls\", None) and not getattr(ev.choices[0], \"finish_reason\", None):\n        print(\"provider emits empty chunks — expect smolagents stream error:\", ev)","typeGuard":"null","tryCatchPattern":"try:\n    for chunk in model.generate_stream(messages):\n        ...\nexcept ValueError as e:\n    if \"No content or tool calls\" in str(e):\n        result = model.generate(messages)  # fallback to non-streaming\n    else:\n        raise","preventionTips":["Smoke-test generate_stream for each new provider/model before enabling streaming in production.","Keep smolagents and litellm versions in lockstep and pinned.","Keep a non-streaming fallback path in agent code."],"tags":["litellm","streaming","smolagents","sse","delta-chunk"],"backgroundTag":"llm-streaming-malformed-chunk","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}