PrefectHQ/fastmcp · error · ValueError

No content in response from completion (finish_reason={finis

Error message

No content in response from completion (finish_reason={finish})

What it means

On the tool-calling sampling path (_response_to_result_with_tools), the handler collected no usable content parts (thought parts are filtered out) from the candidate, so it cannot build a CreateMessageResultWithTools. The finish_reason is included to aid diagnosis.

Source

Thrown at fastmcp_slim/fastmcp/client/sampling/handlers/google_genai.py:400

            # Note: Skip thought parts from thinking_config - not relevant for MCP responses
            if part.text and not part.thought:
                content.append(TextContent(type="text", text=part.text))
            elif part.function_call is not None:
                fc = part.function_call
                fc_name: str = fc.name or "unknown"
                content.append(
                    ToolUseContent(
                        type="tool_use",
                        id=f"{fc_name}_{uuid4().hex[:8]}",  # Generate unique ID
                        name=fc_name,
                        input=dict(fc.args) if fc.args else {},
                    )
                )

    if not content:
        finish = candidate.finish_reason if candidate else "unknown"
        msg = f"No content in response from completion (finish_reason={finish})"
        raise ValueError(msg)

    return CreateMessageResultWithTools(
        content=content,
        role="assistant",
        model=model,
        stop_reason=stop_reason,
    )

View on GitHub (pinned to 1f02114297)

Solutions

  1. Check finish_reason in the error message and address the underlying cause (safety block, truncation).
  2. Reduce or disable thinking output so the model emits final content.
  3. Increase max_tokens for the sampling request.
  4. Verify tool declarations are valid; adjust prompts if the model refuses to answer.
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try:
    result = await client.sample(messages=messages, tools=tools, ...)
except ValueError as e:
    if 'No content in response from completion' in str(e):
        result = await retry_with_revised_request()
    else:
        raise

Prevention

When it happens

Trigger: A Gemini response contains only thought/reasoning parts (filtered), or the candidate is empty/blocked, while processing a sampling request that included tools.

Common situations: Thinking models spending all output on reasoning; SAFETY/RECITATION finish reasons with no text; malformed tool declarations causing immediate stop; zero max_tokens.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/5907bfec44c43ad9. Report an issue: GitHub.