PrefectHQ/fastmcp · error · ValueError
No candidate in response from completion.
Error message
No candidate in response from completion.
What it means
After a completion call, the handler expects the Gemini response to contain at least one candidate. If response.candidates is empty or the first candidate is falsy, ValueError is raised. Candidates can be absent when the request is blocked (safety filters, invalid request) before any generation happens.
Source
Thrown at fastmcp_slim/fastmcp/client/sampling/handlers/google_genai.py:319
part = _sampling_content_to_google_genai_part(content)
if message.role == "user":
google_messages.append(UserContent(parts=[part]))
elif message.role == "assistant":
google_messages.append(ModelContent(parts=[part]))
else:
msg = f"Invalid message role: {message.role}"
raise ValueError(msg)
return google_messages
def _get_candidate_from_response(response: GenerateContentResponse) -> Candidate:
"""Extract the first candidate from a response."""
if response.candidates and response.candidates[0]:
return response.candidates[0]
msg = "No candidate in response from completion."
raise ValueError(msg)
def _response_to_create_message_result(
response: GenerateContentResponse,
model: str,
) -> CreateMessageResult:
"""Convert Google GenAI response to CreateMessageResult (no tools)."""
if not (text := response.text):
candidate = _get_candidate_from_response(response)
# Check if the response only contained thinking
has_thoughts = (
candidate.content
and candidate.content.parts
and all(getattr(p, "thought", False) for p in candidate.content.parts)
)
if has_thoughts:
msg = (
"Model returned only thinking/reasoning content with no response text."View on GitHub (pinned to 1f02114297)
Solutions
- Inspect response.prompt_feedback for a blockReason and adjust the request content or safety settings.
- Relax or configure safety settings on the google-genai client (safety_settings) if legitimate content is being blocked.
- Retry the request; transient blocks can occur.
- Check model name and API key validity — invalid configs can yield empty responses.
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try:
result = await client.sample(...)
except ValueError as e:
if 'No candidate in response' in str(e):
# inspect prompt_feedback / adjust safety settings, then retry
result = await retry_sample_with_relaxed_safety()
else:
raise Prevention
- Configure safety_settings appropriately for your content domain.
- Check prompt content against known safety trigger patterns before sampling.
- Retry transient empty responses with backoff.
When it happens
Trigger: _get_candidate_from_response is invoked from _response_to_create_message_result or _response_to_result_with_tools when the GenerateContentResponse from the Gemini API has no candidates (e.g. response was blocked by safety filters or prompt blocked).
Common situations: Safety settings filtering the prompt entirely; quota/blocked requests surfacing as empty responses; models returning only promptFeedback with a blockReason; network/proxy truncation.
Related errors
- Model returned only thinking/reasoning content with no respo
- No content in response from completion (finish_reason={finis
- No content in response from Anthropic
- Unsupported tool result content type: {type(item).__name__}
- Unsupported content type: {type(content)}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/73b6658a832e9a76.
Report an issue: GitHub.