{"record":{"id":"f2eb67c745452158","repo":"tinyhumansai/openhuman","slug":"the-model-returned-an-empty-response-please-try-a","errorCode":null,"errorMessage":"The model returned an empty response. Please try again.","messagePattern":"The model returned an empty response\\. Please try again\\.","errorType":"exception","errorClass":"AgentError::EmptyProviderResponse","httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/harness/session/turn/core.rs","lineNumber":1434,"sourceCode":"            // branch below pops that dangling blank row before re-prompting, but\n            // this `tool_calls == 0` path returned the error with the empty row\n            // still in history — so the *next* request carried an empty-content\n            // assistant message and strict providers (Anthropic: \"text content\n            // blocks must be non-empty\") 400 the whole thread, not just this turn.\n            // Pop the trailing empty assistant row before returning so a retry\n            // sends a clean transcript.\n            if matches!(\n                self.history.last(),\n                Some(ConversationMessage::Chat(msg))\n                    if msg.role == \"assistant\" && msg.content.trim().is_empty()\n            ) {\n                log::debug!(\n                    \"[agent_loop] EmptyProviderResponse at iteration {}: popping dangling empty assistant row before returning — #4457 defect A\",\n                    outcome.model_calls\n                );\n                self.history.pop();\n            }\n            return Err(anyhow::Error::new(\n                crate::openhuman::agent::error::AgentError::EmptyProviderResponse {\n                    iteration: outcome.model_calls,\n                },\n            ));\n        } else if outcome.text.trim().is_empty() {\n            // #4093: the loop ran tool calls (tool_calls > 0, so the branch\n            // above did not fire) and then yielded a terminating response with\n            // no final text — the turn did work but would otherwise end\n            // silently, leaving the user with nothing. Enforce the\n            // \"must produce a final response\" terminal step: re-prompt the\n            // model (tools disabled) for a closing summary of what it did,\n            // falling back to a deterministic summary of the tool calls so the\n            // synthesized message is never itself empty. Fold the extra call's\n            // usage into the turn accounting, exactly like the cap path above.\n            let base = self.tool_dispatcher.to_provider_messages(&self.history);\n            let (summary, summary_usage) = self\n                .summarize_turn_wrapup(\n                    &base,","sourceCodeStart":1416,"sourceCodeEnd":1452,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/agent/harness/session/turn/core.rs#L1416-L1452","documentation":"End-of-turn guard in the agent harness: the model reply contained no text and no tool calls. The trailing empty assistant row is popped from history first (so strict providers like Anthropic don't 400 the next request on an empty content block), then this user-facing retry prompt is returned.","triggerScenarios":"Thrown at src/openhuman/agent/harness/session/turn/core.rs:1434 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the turn — the transcript is clean, so a re-prompt usually gets a real reply","If recurring, check provider health/model availability for degraded empty completions"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}