{"record":{"id":"77ba7c0fa091906d","repo":"FoundationAgents/OpenManus","slug":"empty-or-invalid-response-from-llm","errorCode":null,"errorMessage":"Empty or invalid response from LLM","messagePattern":"Empty or invalid response from LLM","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"app/llm.py","lineNumber":426,"sourceCode":"                \"messages\": messages,\n            }\n\n            if self.model in REASONING_MODELS:\n                params[\"max_completion_tokens\"] = self.max_tokens\n            else:\n                params[\"max_tokens\"] = self.max_tokens\n                params[\"temperature\"] = (\n                    temperature if temperature is not None else self.temperature\n                )\n\n            if not stream:\n                # Non-streaming request\n                response = await self.client.chat.completions.create(\n                    **params, stream=False\n                )\n\n                if not response.choices or not response.choices[0].message.content:\n                    raise ValueError(\"Empty or invalid response from LLM\")\n\n                # Update token counts\n                self.update_token_count(\n                    response.usage.prompt_tokens, response.usage.completion_tokens\n                )\n\n                return response.choices[0].message.content\n\n            # Streaming request, For streaming, update estimated token count before making the request\n            self.update_token_count(input_tokens)\n\n            response = await self.client.chat.completions.create(**params, stream=True)\n\n            collected_messages = []\n            completion_text = \"\"\n            async for chunk in response:\n                chunk_message = chunk.choices[0].delta.content or \"\"\n                collected_messages.append(chunk_message)","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/llm.py#L408-L444","documentation":"Raised in LLM.ask_with_tools() non-streaming branch when the API returns a response with no choices array or an empty message.content. This can be legitimate model behavior (the model emitted nothing, possibly because content went to reasoning or was filtered) rather than a transport failure, so it is treated as a hard ValueError after the request succeeded.","triggerScenarios":"Calling ask_with_tools(..., stream=False) where the provider returns choices: [] or a message whose content is empty/None; models that put output into refusal or reasoning fields; content-filtered responses from hosted endpoints.","commonSituations":"Using a reasoning model whose visible content is empty when max_tokens is exhausted mid-reasoning; proxy/gateway rewriting responses and dropping content; aggressive content moderation returning empty completions.","solutions":["Increase max_tokens (or max_completion_tokens for reasoning models) so the model finishes reasoning and emits content","Retry the request — transient empty completions from load-balanced endpoints often succeed on the next call","Inspect the raw response (log response.choices[0]) to see whether content moved to refusal/tool_calls/reasoning fields and adapt extraction"],"exampleFix":"# config.toml before\nmax_tokens = 128\n\n# after\nmax_tokens = 4096","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        text = await llm.ask_with_tools(messages, tools, stream=False)\n        break\n    except ValueError as e:\n        if \"Empty or invalid response\" in str(e) and attempt == 0:\n            continue\n        raise","preventionTips":["Set max_tokens generously enough for reasoning models to emit content","Log raw API responses when empty completions recur to spot filtering/refusals","Retry empty non-streaming responses once before surfacing the error to users"],"tags":["llm","response","provider","retry"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}