{"record":{"id":"41577e53477edc63","repo":"harry0703/MoneyPrinterTurbo","slug":"llm-provider-returned-empty-response","errorCode":null,"errorMessage":"[{llm_provider}] returned empty response","messagePattern":"\\[(.+?)\\] returned empty response","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"app/services/llm.py","lineNumber":323,"sourceCode":"            )\n            return _extract_chat_completion_text(response, llm_provider)\n\n        if adapter == \"litellm\":\n            import litellm\n\n            if not model_name:\n                raise ValueError(\n                    f\"{llm_provider}: model_name is not set, please set it in the config.toml file.\"\n                )\n\n            response = litellm.completion(\n                model=model_name,\n                messages=[{\"role\": \"user\", \"content\": prompt}],\n                drop_params=True,\n            )\n\n            if not response:\n                raise ValueError(f\"[{llm_provider}] returned empty response\")\n            if not getattr(response, \"choices\", None):\n                raise ValueError(f\"[{llm_provider}] returned empty response\")\n\n            return _extract_chat_completion_text(response, llm_provider)\n\n        if adapter == \"azure\":\n            # Azure OpenAI SDK 使用 `azure_endpoint` 和 `api_version` 生成专用请求地址，\n            # 不能继续复用下面普通 OpenAI-compatible 的 `base_url` 初始化逻辑。\n            # 这里在 Azure 分支内完成请求并立即返回，避免客户端被后续 fallback\n            # 覆盖，导致用户配置的 Azure 凭证通过校验但实际请求没有被使用。\n            logger.info(f\"requesting azure chat completion, model: {model_name}\")\n            client = AzureOpenAI(\n                api_key=api_key,\n                api_version=api_version,\n                azure_endpoint=base_url,\n            )\n            response = client.chat.completions.create(\n                model=model_name, messages=[{\"role\": \"user\", \"content\": prompt}]","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/llm.py#L305-L341","documentation":"Raised in the litellm branch when litellm.completion() returns a falsy response object. litellm normally raises its own exceptions on failure, so a falsy return is an SDK-contract anomaly — most often seen with drop_params=True silently stripping parameters on an incompatible provider, or mocked litellm in tests.","triggerScenarios":"litellm.completion(model=..., messages=[...], drop_params=True) evaluating False under `if not response:` — e.g. a litellm version returning None on certain internal routing failures, unsupported model/provider strings falling through, or a test mock returning None.","commonSituations":"Upgrading litellm major versions (its return contract and exception behavior changed across releases); passing a model string litellm cannot resolve to any provider; unit tests patching litellm.completion without a return value; edge failure modes inside litellm's router.","solutions":["Check litellm logs/verbose output (litellm.set_verbose=True or check logger) for the routing failure that preceded the empty return","Pin a known-good litellm version: the model-string routing contract changed between major versions; reinstall in a clean venv","Verify the model string format for the target provider (e.g. 'groq/llama-3.1-8b-instant') and that the matching credentials env vars (GROQ_API_KEY, etc.) are set","In tests, make the litellm.completion mock return a real ModelResponse with choices"],"exampleFix":"# before\nresponse = litellm.completion(model=model_name, messages=[...], drop_params=True)\nif not response:\n    raise ValueError(f\"[{llm_provider}] returned empty response\")\n\n# after\nresponse = litellm.completion(model=model_name, messages=[...], drop_params=True)\nif not response:\n    raise ValueError(\n        f\"[{llm_provider}] litellm returned empty response for model \"\n        f\"'{model_name}'; check provider prefix and credentials\"\n    )","handlingStrategy":"validation","validationCode":"import litellm\nif not hasattr(litellm, \"completion\"):\n    raise RuntimeError(\"litellm not installed\")\n# verify model routes: litellm.get_model_info or a 1-token dry run\nresp = litellm.completion(model=model_name, messages=[{\"role\":\"user\",\"content\":\"hi\"}], max_tokens=1)\nassert resp and resp.choices","typeGuard":null,"tryCatchPattern":"except ValueError: — check the model string and credentials once, then fail; retrying an empty return from the same model usually repeats","preventionTips":["Pin the litellm version; its return contract shifts between majors","Dry-run litellm with max_tokens=1 when adding a new provider config","Set required provider env keys (e.g. GROQ_API_KEY) before starting jobs"],"tags":["llm","litellm","sdk-bug","configuration"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}