{"record":{"id":"6031d304e32211a9","repo":"NousResearch/hermes-agent","slug":"provider-returned-an-empty-stream-with-no-finish-r","errorCode":null,"errorMessage":"Provider returned an empty stream with no finish_reason (possible upstream error or malformed SSE response).","messagePattern":"Provider returned an empty stream with no finish_reason \\(possible upstream error or malformed SSE response\\)\\.","errorType":"exception","errorClass":"EmptyStreamError","httpStatus":null,"severity":"error","filePath":"agent/chat_completion_helpers.py","lineNumber":3770,"sourceCode":"                    id=tc[\"id\"],\n                    type=tc[\"type\"],\n                    extra_content=tc.get(\"extra_content\"),\n                    function=SimpleNamespace(\n                        name=tc[\"function\"][\"name\"],\n                        arguments=arguments,\n                    ),\n                ))\n\n        # Zero-chunk guard: stream yielded nothing usable — a provider/upstream\n        # error or malformed SSE, not a legitimate empty completion. Raise so the\n        # retry machinery handles it instead of fabricating a successful turn.\n        if (\n            finish_reason is None\n            and not content_parts\n            and not reasoning_parts\n            and not tool_calls_acc\n        ):\n            raise EmptyStreamError(\n                \"Provider returned an empty stream with no finish_reason \"\n                \"(possible upstream error or malformed SSE response).\"\n            )\n\n        # A stream that delivered a tool call but only partial/unparseable\n        # JSON args splits into two very different cases:\n        #\n        #   1. Provider sent finish_reason=\"length\" → a genuine output-cap\n        #      truncation.  Boosting max_tokens on retry is the right move.\n        #\n        #   2. Provider sent NO finish_reason (the SSE simply stopped after\n        #      the opening \"{\" with no terminator and no [DONE]) → the\n        #      upstream dropped/stalled the connection mid tool-call.  This\n        #      is NOT an output cap — the model never reported hitting one.\n        #      Some dedicated endpoints (e.g. NVIDIA Nemotron Ultra on the\n        #      Nous dedicated endpoint) stall for minutes during large\n        #      tool-arg generation, then close the stream cleanly without a\n        #      finish_reason.  Stamping \"length\" here sends it down the","sourceCodeStart":3752,"sourceCodeEnd":3788,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/chat_completion_helpers.py#L3752-L3788","documentation":"Error \"Provider returned an empty stream with no finish_reason (possible upstream error or malformed SSE response).\" thrown in NousResearch/hermes-agent.","triggerScenarios":"Thrown at agent/chat_completion_helpers.py:3770 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the request; the provider returned an empty stream, often transient.","Check provider status and the request parameters (model name, max_tokens).","Switch models/providers if the endpoint consistently returns empty streams."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}