huggingface/smolagents · error · ValueError

No content or tool calls in event: {event}

Error message

No content or tool calls in event: {event}

What it means

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.

Source

Thrown at src/smolagents/models.py:1360

                choice = event.choices[0]
                if choice.delta:
                    yield ChatMessageStreamDelta(
                        content=choice.delta.content,
                        tool_calls=[
                            ChatMessageToolCallStreamDelta(
                                index=delta.index,
                                id=delta.id,
                                type=delta.type,
                                function=delta.function,
                            )
                            for delta in choice.delta.tool_calls
                        ]
                        if choice.delta.tool_calls
                        else None,
                    )
                else:
                    if not getattr(choice, "finish_reason", None):
                        raise ValueError(f"No content or tool calls in event: {event}")


class LiteLLMRouterModel(LiteLLMModel):
    """Router‑based client for interacting with the [LiteLLM Python SDK Router](https://docs.litellm.ai/docs/routing).

    This class provides a high-level interface for distributing requests among multiple language models using
    the LiteLLM SDK's routing capabilities. It is responsible for initializing and configuring the router client,
    applying custom role conversions, and managing message formatting to ensure seamless integration with various LLMs.

    Parameters:
        model_id (`str`):
            Identifier for the model group to use from the model list (e.g., "model-group-1").
        model_list (`list[dict[str, Any]]`):
            Model configurations to be used for routing.
            Each configuration should include the model group name and any necessary parameters.
            For more details, refer to the [LiteLLM Routing](https://docs.litellm.ai/docs/routing#quick-start) documentation.
        client_kwargs (`dict[str, Any]`, *optional*):
            Additional configuration parameters for the Router client. For more details, see the

View on GitHub (pinned to 30bb116109)

Solutions

  1. Upgrade (or pin) litellm to the latest version — chunk normalization fixes land frequently.
  2. Print/log the raw event shown in the message to identify which field is missing and from which provider it comes.
  3. 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.
  4. Fall back to non-streaming generate() while investigating.

Example fix

# before
for chunk in model.generate_stream(messages):  # ValueError: No content or tool calls in event
    ...

# after
msg = model.generate(messages)  # non-streaming path while provider chunk issue is investigated
print(msg.content)
Defensive patterns

Strategy: try-catch

Validate before calling

import litellm
stream = litellm.completion(model=model_id, messages=[{"role":"user","content":"ping"}], stream=True)
for ev in stream:
    delta = ev.choices[0].delta if ev.choices else None
    if delta and not getattr(delta, "content", None) and not getattr(delta, "tool_calls", None) and not getattr(ev.choices[0], "finish_reason", None):
        print("provider emits empty chunks — expect smolagents stream error:", ev)

Type guard

null

Try / catch

try:
    for chunk in model.generate_stream(messages):
        ...
except ValueError as e:
    if "No content or tool calls" in str(e):
        result = model.generate(messages)  # fallback to non-streaming
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/f4b26e1f3800f5aa. Report an issue: GitHub.