{"record":{"id":"3f98da3d9612d729","repo":"spring-projects/spring-ai","slug":"thinkinglevel-s-is-not-supported-for-model-s","errorCode":null,"errorMessage":"ThinkingLevel.%s is not supported for model '%s'. This model does not support thinkingLevel; use thinkingBudget instead.","messagePattern":"ThinkingLevel\\.(.+?) is not supported for model '(.+?)'\\. This model does not support thinkingLevel; use thinkingBudget instead\\.","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java","lineNumber":926,"sourceCode":"\t * @param level the thinking level to validate\n\t * @param modelName the model name\n\t * @throws IllegalArgumentException if the level is not supported for the model\n\t */\n\tprivate static void validateThinkingLevelForModel(GoogleGenAiThinkingLevel level, String modelName) {\n\t\tif (level == null || level == GoogleGenAiThinkingLevel.THINKING_LEVEL_UNSPECIFIED || modelName == null) {\n\t\t\treturn;\n\t\t}\n\t\t// Vertex AI style full resource names (e.g.\n\t\t// \"projects/{project}/locations/{location}/publishers/google/models/{model}\")\n\t\t// carry the model id as the last path segment.\n\t\tString modelId = modelName.substring(modelName.lastIndexOf('/') + 1).toLowerCase(Locale.ROOT);\n\t\tSet<GoogleGenAiThinkingLevel> supportedLevels = THINKING_LEVEL_SUPPORT_BY_MODEL.get(modelId);\n\t\tif (supportedLevels == null) {\n\t\t\treturn;\n\t\t}\n\t\tif (!supportedLevels.contains(level)) {\n\t\t\tif (supportedLevels.isEmpty()) {\n\t\t\t\tthrow new IllegalArgumentException(String.format(\n\t\t\t\t\t\t\"ThinkingLevel.%s is not supported for model '%s'. This model does not support thinkingLevel; use thinkingBudget instead.\",\n\t\t\t\t\t\tlevel, modelName));\n\t\t\t}\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\tString.format(\"ThinkingLevel.%s is not supported for model '%s'. Supported levels: %s.\", level,\n\t\t\t\t\t\t\tmodelName, supportedLevels.stream().map(Enum::name).collect(Collectors.joining(\", \"))));\n\t\t}\n\t}\n\n\tprivate List<Content> toGeminiContent(List<Message> instructions) {\n\n\t\tList<Content> contents = instructions.stream()\n\t\t\t.map(message -> Content.builder()\n\t\t\t\t.role(toGeminiMessageType(message.getMessageType()).getValue())\n\t\t\t\t.parts(messageToGeminiParts(message))\n\t\t\t\t.build())\n\t\t\t.toList();\n","sourceCodeStart":908,"sourceCodeEnd":944,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java#L908-L944","documentation":"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.","triggerScenarios":"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.","commonSituations":"Reusing chat options across model IDs; upgrading model names without revisiting thinking configuration; defaults that carry thinkingLevel into requests for non-thinking-capable models.","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."],"exampleFix":"// before\nGoogleGenAiChatOptions.builder().model(\"gemini-2.0-flash\")\n    .thinkingLevel(GoogleGenAiThinkingLevel.THINKING_LEVEL_HIGH).build();\n// after\nGoogleGenAiChatOptions.builder().model(\"gemini-2.0-flash\")\n    .thinkingBudget(1024).build();","handlingStrategy":"validation","validationCode":"if (\"gemini-2.0-flash\".equals(options.getModel()) && options.getThinkingLevel() != null) {\n    throw new IllegalStateException(\"model does not support thinkingLevel; use thinkingBudget\");\n}","typeGuard":null,"tryCatchPattern":"try { model.call(prompt); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"use thinkingBudget instead\")) rebuildOptionsWithBudget(); else throw e; }","preventionTips":["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"],"tags":["thinking","config","gemini","validation"],"backgroundTag":"unsupported-config-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}