{"record":{"id":"84147f25fcce3bed","repo":"zylon-ai/private-gpt","slug":"no-items-returned-from-astream-structured-chat","errorCode":null,"errorMessage":"No items returned from astream_structured_chat","messagePattern":"No items returned from astream_structured_chat","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/llm/custom/structured_mixin.py","lineNumber":223,"sourceCode":"        self,\n        output_cls: type[Model],\n        messages: Sequence[ChatMessage],\n        tools: Sequence[BaseTool] | None = None,\n        reasoning_effort: ReasoningEffort = ReasoningEffort.NONE,\n        allow_flexible: bool = False,\n        **kwargs: Any,\n    ) -> \"Model | FlexibleModel\":\n        items: list[Model | FlexibleModel] = []\n        async for item in await self.astream_structured_chat(\n            output_cls=output_cls,\n            messages=messages,\n            tools=tools,\n            reasoning_effort=reasoning_effort,\n            **kwargs,\n        ):\n            items.append(item)\n        if not items:\n            raise ValueError(\"No items returned from astream_structured_chat\")\n        last_item: Model | FlexibleModel = items[-1]\n        if isinstance(last_item, FlexibleModel) and not allow_flexible:\n            raise ValueError(\n                \"Last item is a FlexibleModel, expected a specific output_cls.\"\n            )\n        return last_item\n\n    async def astream_structured_chat(\n        self,\n        output_cls: type[Model],\n        messages: Sequence[ChatMessage],\n        tools: Sequence[BaseTool] | None = None,\n        reasoning_effort: ReasoningEffort = ReasoningEffort.NONE,\n        **kwargs: Any,\n    ) -> typing.AsyncGenerator[Model | FlexibleModel, None]:\n        from partial_json_parser.core.options import Allow\n\n        from private_gpt.components.llm.custom.base import StructuredOutputsParams","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/llm/custom/structured_mixin.py#L205-L241","documentation":"Raised by the non-streaming wrapper around astream_structured_chat when the async generator yielded zero items before completing. The wrapper must return the last item of the stream; an empty stream means no chat response (not even a FlexibleModel fallback) was ever produced, which indicates the underlying LLM call failed silently or produced nothing parseable.","triggerScenarios":"Calling the structured chat wrapper (structured_chat or the consume-all helper around astream_structured_chat) when the underlying stream ends without yielding: empty completion from the backend, immediate stream termination, cancellation, or an exception path in the backend that closes the generator without emitting items.","commonSituations":"Misconfigured endpoint returning an empty response; overly aggressive content filters blocking all output; context window exceeded so the model emits nothing; transient backend failures during streaming.","solutions":["Retry the call — empty streams are often transient backend/streaming failures.","Check the LLM backend logs/health: verify the model responded with actual content for the exact messages sent.","Log the raw messages and llm_kwargs to confirm the request is well-formed (non-empty prompt, valid tool definitions).","If using a proxy or OpenAI-compatible server, confirm it fully supports the chat/structured endpoint being used."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        result = await llm.structured_chat(MyModel, messages=messages)\n        break\n    except ValueError as e:\n        if 'No items returned' not in str(e) or attempt == 2:\n            raise","preventionTips":["Health-check the LLM endpoint before batch jobs so silent empty responses surface early.","Monitor empty-stream rates; a spike usually means backend or filter problems, not code bugs.","Keep prompts non-empty and tool schemas valid — degenerate requests often yield empty streams."],"tags":["llm","streaming","empty-response","structured-output"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}