spring-projects/spring-ai · error · java.lang.RuntimeException
Failed to generate content
Error message
Failed to generate content
What it means
internalStream wraps any exception occurring while setting up or starting the streaming generateContent call into RuntimeException("Failed to generate content", e). It signals that the streaming request to the Gemini API could not be created or initiated.
Source
Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java:515
toChatResponseMetadata(cumulativeUsage, response.modelVersion().get()));
return Flux.just(chatResponse);
});
AtomicReference<ChatResponse> aggregatedResponseRef = new AtomicReference<>();
Flux<ChatResponse> aggregatedFlux = new MessageAggregator().aggregate(chatResponseFlux,
aggregatedResponse -> {
aggregatedResponseRef.set(aggregatedResponse);
observationContext.setResponse(aggregatedResponse);
});
return aggregatedFlux.doOnError(observation::error)
.doFinally(s -> observation.stop())
.contextWrite(ctx -> ctx.put(ObservationThreadLocalAccessor.KEY, observation));
}
catch (Exception e) {
throw new RuntimeException("Failed to generate content", e);
}
});
}
protected List<Generation> responseCandidateToGeneration(Candidate candidate) {
// TODO - The candidateIndex (e.g. choice must be assigned to the generation).
int candidateIndex = candidate.index().orElse(0);
FinishReason candidateFinishReason = candidate.finishReason().orElse(new FinishReason(FinishReason.Known.STOP));
Map<String, Object> messageMetadata = new HashMap<>();
messageMetadata.put("candidateIndex", candidateIndex);
messageMetadata.put("finishReason", candidateFinishReason);
// Extract thought signatures from response parts if present
if (candidate.content().isPresent() && candidate.content().get().parts().isPresent()) {
List<Part> parts = candidate.content().get().parts().get();View on GitHub (pinned to 98a7beda4f)
Solutions
- Read the cause (getCause()) for the underlying genai SDK error.
- Verify the model name and request options (temperature, safety settings, thinking config) are valid for that model.
- Check API key/credentials and region configuration.
- Ensure prompt media parts reference readable resources with detectable MIME types.
Example fix
// before
flux = chatModel.stream(new Prompt("hello")); // throws "Failed to generate content"
// after
try {
flux = chatModel.stream(new Prompt("hello"));
} catch (RuntimeException e) {
logger.error("stream failed", e.getCause());
} Defensive patterns
Strategy: try-catch
Validate before calling
// before streaming, validate options Assert.hasText(options.getModel(), "model must be set");
Try / catch
try { chatModel.stream(prompt).subscribe(...) } catch (RuntimeException e) { handleCause(e.getCause()); } Prevention
- Validate model names and options before streaming
- Log getCause() to surface the real SDK error
- Keep the genai SDK version aligned with the Spring AI module
When it happens
Trigger: Calling ChatModel.stream(prompt) when the underlying client.createContent / generateContentStream setup throws: invalid request configuration, client initialization failure, missing model, or errors from the genai SDK during streaming setup.
Common situations: Invalid model name in options; malformed contents/config built from the prompt; the genai client failing to authenticate or build the streaming call; SDK version mismatches.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Incomplete Google GenAI configuration: Provide 'api-key' for
- Streaming chat completion is not supported for this model:
- Currently only one tool call is supported per message!
- Gemini doesn't support message type:
- Unknown HarmCategory:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6d575d7e98da9c63.
Report an issue: GitHub.