harry0703/MoneyPrinterTurbo · error · ValueError
[{llm_provider}] returned invalid response content
Error message
[{llm_provider}] returned invalid response content What it means
Raised in the gemini adapter branch when reading response.text from google-genai raises AttributeError, IndexError, or ValueError. The google.genai SDK raises ValueError ('response.text' when part candidates lack text) when the model returns no usable text — typically because all candidates were blocked by safety filters or came back empty. The original exception is logged as a warning before re-raising.
Source
Thrown at app/services/llm.py:285
],
)
try:
# 新版 google-genai 通过统一 Client 暴露模型服务。上下文管理器
# 会在请求结束后关闭底层 HTTP 连接,避免频繁生成时积累连接资源。
with genai.Client(
api_key=api_key,
http_options=http_options,
) as client:
response = client.models.generate_content(
model=model_name,
contents=prompt,
config=generation_config,
)
generated_text = response.text
except (AttributeError, IndexError, ValueError) as e:
logger.warning(f"gemini returned invalid response content: {str(e)}")
raise ValueError(f"[{llm_provider}] returned invalid response content")
return _normalize_text_response(generated_text, llm_provider)
if adapter == "cloudflare_ai_gateway":
account_id = extra_values["account_id"]
gateway_id = extra_values["gateway_id"]
# Cloudflare 当前推荐的 AI Gateway REST API 兼容 OpenAI SDK。
# Account ID 用于构造统一端点,Gateway ID 通过请求头选择;这里
# 不再调用 Workers AI 的 /ai/run/{model} 专用接口。
client = OpenAI(
api_key=api_key,
base_url=(
f"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1"
),
default_headers={"cf-aig-gateway-id": gateway_id},
)
response = client.chat.completions.create(
model=model_name,View on GitHub (pinned to 1f9f19c202)
Solutions
- Check the logged warning immediately preceding the raise — it contains the underlying SDK error naming the exact cause (safety block vs empty parts)
- If safety-related, rephrase the prompt or lower risk settings; inspect response.candidates[0].finish_reason and safety_ratings in a debug run
- For MAX_TOKENS/empty-output, raise max_output_tokens or switch model (e.g. gemini-2.x non-thinking variant)
- Verify the google-genai package (not legacy google-generativeai) is installed and matches the SDK this code targets
- Retry once via the existing retry loop — transient empty responses do occur
Example fix
# before
response = client.models.generate_content(model=model_name, contents=prompt, config=generation_config)
generated_text = response.text # raises ValueError when candidates blocked
# after
response = client.models.generate_content(model=model_name, contents=prompt, config=generation_config)
if not response.candidates:
raise ValueError(f"[{llm_provider}] no candidates returned (finish_reason={getattr(response.candidates[0], 'finish_reason', 'n/a') if response.candidates else 'none'})")
generated_text = response.text Defensive patterns
Strategy: try-catch
Type guard
def gemini_has_text(response) -> bool:
try:
return bool(response and response.text and response.text.strip())
except (AttributeError, ValueError, IndexError):
return False Try / catch
except ValueError as e: — the code already narrows to (AttributeError, IndexError, ValueError) around response.text; callers should retry once (transient safety blocks happen) but rephrase the prompt if a specific subject consistently triggers it
Prevention
- Pre-check the video subject prompt for obviously sensitive terms before sending
- Keep prompts short and neutral — long prompts raise Gemini block probability
- Capture the warning log line to identify finish_reason (SAFETY vs empty parts) for each failure
When it happens
Trigger: client.models.generate_content(...) succeeds HTTP-wise but response.text raises: candidate.finish_reason == SAFETY (prompt blocked), all parts empty (MAX_TOKENS with no output), recitation filter, or response object lacking expected attributes (SDK version mismatch); also prompt rejected by Gemini's content policy.
Common situations: Video script/keyword prompts occasionally tripping Gemini safety filters; old google-generativeai vs new google-genai package confusion; max_output_tokens=2048 with thinking models producing empty text; prompts with sensitive words (violence, medical) in the video subject; regional restrictions returning empty candidates.
Related errors
- [{llm_provider}] returned empty text content
- [{llm_provider}] returned non-text content: {type(content)._
- [{llm_provider}] returned empty choices
- [{llm_provider}] returned empty message
- [qwen] returned empty choices
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/7b78a952cd1900a4.
Report an issue: GitHub.