spring-projects/spring-ai · error · java.lang.IllegalArgumentException
ThinkingLevel.%s is not supported for model '%s'. This model
Error message
ThinkingLevel.%s is not supported for model '%s'. This model does not support thinkingLevel; use thinkingBudget instead.
What it means
When validating ThinkingLevel options against the target model, a model whose supported-level set is empty (i.e. it does not support thinkingLevel at all) triggers this IllegalArgumentException telling you to use thinkingBudget instead.
Source
Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java:926
* @param level the thinking level to validate
* @param modelName the model name
* @throws IllegalArgumentException if the level is not supported for the model
*/
private static void validateThinkingLevelForModel(GoogleGenAiThinkingLevel level, String modelName) {
if (level == null || level == GoogleGenAiThinkingLevel.THINKING_LEVEL_UNSPECIFIED || modelName == null) {
return;
}
// Vertex AI style full resource names (e.g.
// "projects/{project}/locations/{location}/publishers/google/models/{model}")
// carry the model id as the last path segment.
String modelId = modelName.substring(modelName.lastIndexOf('/') + 1).toLowerCase(Locale.ROOT);
Set<GoogleGenAiThinkingLevel> supportedLevels = THINKING_LEVEL_SUPPORT_BY_MODEL.get(modelId);
if (supportedLevels == null) {
return;
}
if (!supportedLevels.contains(level)) {
if (supportedLevels.isEmpty()) {
throw new IllegalArgumentException(String.format(
"ThinkingLevel.%s is not supported for model '%s'. This model does not support thinkingLevel; use thinkingBudget instead.",
level, modelName));
}
throw new IllegalArgumentException(
String.format("ThinkingLevel.%s is not supported for model '%s'. Supported levels: %s.", level,
modelName, supportedLevels.stream().map(Enum::name).collect(Collectors.joining(", "))));
}
}
private List<Content> toGeminiContent(List<Message> instructions) {
List<Content> contents = instructions.stream()
.map(message -> Content.builder()
.role(toGeminiMessageType(message.getMessageType()).getValue())
.parts(messageToGeminiParts(message))
.build())
.toList();
View on GitHub (pinned to 98a7beda4f)
Solutions
- Remove the thinkingLevel option for this model.
- Set thinkingBudget instead (e.g. an Integer budget in the options) for models without thinkingLevel support.
- Check the model ID in your options — pick a model that supports thinkingLevel (newer Gemini 2.5+ models) if you need levels.
- Wrap options building per-model so thinking options are only applied to capable models.
Example fix
// before
GoogleGenAiChatOptions.builder().model("gemini-2.0-flash")
.thinkingLevel(GoogleGenAiThinkingLevel.THINKING_LEVEL_HIGH).build();
// after
GoogleGenAiChatOptions.builder().model("gemini-2.0-flash")
.thinkingBudget(1024).build(); Defensive patterns
Strategy: validation
Validate before calling
if ("gemini-2.0-flash".equals(options.getModel()) && options.getThinkingLevel() != null) {
throw new IllegalStateException("model does not support thinkingLevel; use thinkingBudget");
} Try / catch
try { model.call(prompt); } catch (IllegalArgumentException e) { if (e.getMessage().contains("use thinkingBudget instead")) rebuildOptionsWithBudget(); else throw e; } Prevention
- Per-model option profiles: only attach thinkingLevel to models that support it
- Prefer thinkingBudget for older Gemini models
- Centralize options construction and validate against model ID
When it happens
Trigger: Setting thinkingLevel (e.g. via GoogleGenAiChatOptions) on a model that appears in THINKING_LEVEL_SUPPORT_BY_MODEL with an empty supported set — typically older Gemini models like gemini-2.0-flash or 1.5 variants that only accept thinkingBudget.
Common situations: Reusing chat options across model IDs; upgrading model names without revisiting thinking configuration; defaults that carry thinkingLevel into requests for non-thinking-capable models.
Related errors
- ThinkingLevel.%s is not supported for model '%s'. Supported
- Either TTL or expire time must be set for update
- SSE connection '<connectionName>' requires a 'url' property.
- Incomplete Google GenAI configuration: Provide 'api-key' for
- Method must not be null
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/3f98da3d9612d729.
Report an issue: GitHub.