{"record":{"id":"b474d28b12a130ee","repo":"HKUDS/DeepTutor","slug":"cloud-completion-failed-no-valid-configuration","errorCode":null,"errorMessage":"Cloud completion failed: no valid configuration","messagePattern":"Cloud completion failed: no valid configuration","errorType":"error_code","errorClass":"LLMConfigError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/llm/cloud_provider.py","lineNumber":452,"sourceCode":"                raise LLMAPIError(\n                    f\"Connection to {binding} API was forcibly closed. \"\n                    \"This may indicate network issues or server-side problems. \"\n                    \"Please check your internet connection and try again.\",\n                    status_code=0,\n                    provider=binding or \"openai\",\n                ) from e\n            else:\n                raise LLMAPIError(\n                    f\"Network error connecting to {binding} API: {e}\",\n                    status_code=0,\n                    provider=binding or \"openai\",\n                ) from e\n\n    if content is not None:\n        # Clean thinking tags from response using unified utility\n        return clean_thinking_tags(content, binding, model)\n\n    raise LLMConfigError(\"Cloud completion failed: no valid configuration\")\n\n\nasync def _openai_stream(\n    model: str,\n    prompt: str,\n    system_prompt: str,\n    api_key: str | None,\n    base_url: str | None,\n    api_version: str | None = None,\n    binding: str = \"openai\",\n    messages: list[dict[str, object]] | None = None,\n    **kwargs: object,\n) -> AsyncGenerator[str, None]:\n    \"\"\"OpenAI-compatible streaming.\"\"\"\n    import json\n\n    # Sanitize URL\n    if base_url:","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/llm/cloud_provider.py#L434-L470","documentation":"Defensive tail of _openai_complete: the response parsed successfully but no candidate carried textual content (content stayed None), so there is nothing to return and LLMConfigError is raised. In practice it means the endpoint returned a 200 body whose choices/message structure had no usable content field — an 'empty completion' from an OpenAI-compatible server.","triggerScenarios":"Local OpenAI-compatible servers (older vLLM/LM Studio/Ollama builds) returning choices[0].message without content; responses containing only tool_calls or refusal objects; prompt-engineered outputs where the model emitted only whitespace filtered upstream.","commonSituations":"Switching between OpenAI-compatible backends with divergent response schemas; server version change altering payload shape; requesting JSON mode and receiving an empty body; content filtered by a moderation layer.","solutions":["Log the raw response body once to see what the endpoint actually returned.","Update/patch the local server (vLLM/LM Studio/Ollama) to a version with a conforming OpenAI schema.","If tool-calls-only responses are expected, extend extraction to read tool_calls instead of content.","Retry once — some backends intermittently emit empty candidates."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Cannot be validated client-side; mitigate by pinning known-good endpoints:\nassert \"v1\" in (base_url or \"https://api.openai.com/v1\"), \"use a conforming OpenAI-compatible base_url\"","typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        return await complete(prompt=p, model=m)\n    except LLMConfigError as e:\n        if \"no valid configuration\" not in str(e) or attempt == 1:\n            raise\n        await asyncio.sleep(1)","preventionTips":["Pin local-server versions with a verified OpenAI response schema.","Log raw bodies when integrating a new OpenAI-compatible backend.","Fall back to a different provider when empty completions recur."],"tags":["llm","openai","empty-response","unexpected-payload"],"backgroundTag":"llm-empty-response","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}