FoundationAgents/OpenManus · error · ValueError

Empty response from streaming LLM

Error message

Empty response from streaming LLM

What it means

Raised in LLM.ask_with_tools() streaming branch when every SSE chunk's delta.content was empty, so the joined completion text is empty after strip(). It mirrors the non-streaming empty-response check: the request technically succeeded but produced zero visible tokens.

Source

Thrown at app/llm.py:451

                return response.choices[0].message.content

            # Streaming request, For streaming, update estimated token count before making the request
            self.update_token_count(input_tokens)

            response = await self.client.chat.completions.create(**params, stream=True)

            collected_messages = []
            completion_text = ""
            async for chunk in response:
                chunk_message = chunk.choices[0].delta.content or ""
                collected_messages.append(chunk_message)
                completion_text += chunk_message
                print(chunk_message, end="", flush=True)

            print()  # Newline after streaming
            full_response = "".join(collected_messages).strip()
            if not full_response:
                raise ValueError("Empty response from streaming LLM")

            # estimate completion tokens for streaming response
            completion_tokens = self.count_tokens(completion_text)
            logger.info(
                f"Estimated completion tokens for streaming response: {completion_tokens}"
            )
            self.total_completion_tokens += completion_tokens

            return full_response

        except TokenLimitExceeded:
            # Re-raise token limit errors without logging
            raise
        except ValueError:
            logger.exception(f"Validation error")
            raise
        except OpenAIError as oe:
            logger.exception(f"OpenAI API error")

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Raise max_tokens / max_completion_tokens so the model reaches the content phase
  2. Retry once — transient empty streams are common on flaky endpoints
  3. Log the raw chunks to confirm whether delta.reasoning_content or refusal fields carry the output, and handle those cases explicitly
Defensive patterns

Strategy: retry

Try / catch

try:
    text = await llm.ask_with_tools(messages, tools, stream=True)
except ValueError as e:
    if "Empty response from streaming" in str(e):
        text = await llm.ask_with_tools(messages, tools, stream=False)  # fall back to non-streaming
    else:
        raise

Prevention

When it happens

Trigger: Calling ask_with_tools(..., stream=True) where all chunks have delta.content None/"" — e.g. reasoning models streaming only reasoning deltas, max_tokens exhausted before any text token, or a gateway stripping content from chunks.

Common situations: Streaming with a reasoning model without enough max_completion_tokens; provider sending only role/finish chunks; proxies that filter streamed content; moderation-blocked streams.

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/b001bef90c92bd3f. Report an issue: GitHub.