{"record":{"id":"74b0a9f4de6e6eb1","repo":"spring-projects/spring-ai","slug":"model-cannot-be-null-or-empty","errorCode":null,"errorMessage":"model cannot be null or empty","messagePattern":"model cannot be null or empty","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-google-genai-embedding/src/main/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingModel.java","lineNumber":259,"sourceCode":"\t\t\t\t\t\tModelOptionsUtils.mergeOption(requestOptions.getDimensions(), this.options.getDimensions()));\n\n\t\t\tif (requestOptions instanceof GoogleGenAiTextEmbeddingOptions googleOptions) {\n\t\t\t\tbuilder.taskType(ModelOptionsUtils.mergeOption(googleOptions.getTaskType(), this.options.getTaskType()))\n\t\t\t\t\t.title(ModelOptionsUtils.mergeOption(googleOptions.getTitle(), this.options.getTitle()))\n\t\t\t\t\t.autoTruncate(ModelOptionsUtils.mergeOption(googleOptions.getAutoTruncate(),\n\t\t\t\t\t\t\tthis.options.getAutoTruncate()));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbuilder.taskType(this.options.getTaskType())\n\t\t\t\t\t.title(this.options.getTitle())\n\t\t\t\t\t.autoTruncate(this.options.getAutoTruncate());\n\t\t\t}\n\t\t\tmergedOptions = builder.build();\n\t\t}\n\n\t\t// Validate request options\n\t\tif (!StringUtils.hasText(mergedOptions.getModel())) {\n\t\t\tthrow new IllegalArgumentException(\"model cannot be null or empty\");\n\t\t}\n\n\t\treturn new EmbeddingRequest(embeddingRequest.getInstructions(), mergedOptions);\n\t}\n\n\tprivate EmbeddingResponseMetadata generateResponseMetadata(String model, Integer totalTokens) {\n\t\tEmbeddingResponseMetadata metadata = new EmbeddingResponseMetadata();\n\t\tmetadata.setModel(model);\n\t\tUsage usage = getDefaultUsage(totalTokens);\n\t\tmetadata.setUsage(usage);\n\t\treturn metadata;\n\t}\n\n\tprivate DefaultUsage getDefaultUsage(Integer totalTokens) {\n\t\treturn new DefaultUsage(0, 0, totalTokens);\n\t}\n\n\t@Override","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-google-genai-embedding/src/main/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingModel.java#L241-L277","documentation":"buildEmbeddingRequest() merges model-level GoogleGenAiTextEmbeddingOptions with per-request options and validates the result before creating the EmbeddingRequest. If the merged options still have no model name (null or empty), the request cannot name a Gemini embedding model, so this IllegalArgumentException is thrown. The library does not silently fall back to a default in this path.","triggerScenarios":"Calling embeddingRequest(...) when neither the model default options nor the request EmbeddingOptions specify a model, or when the request options explicitly set model to \"\"/null overriding a valid model default.","commonSituations":"Constructing GoogleGenAiTextEmbeddingModel without setting options.model (e.g. builder with only an API key); passing per-request options that zero out the model; refactors renaming the model field so it is no longer populated; copying options objects and dropping the model field.","solutions":["Set the model on the model-level options: GoogleGenAiTextEmbeddingOptions.builder().model(\"gemini-embedding-001\").build() when constructing the embedding model.","Set the model on the per-request options: new EmbeddingRequest(texts, GoogleGenAiTextEmbeddingOptions.builder().model(\"gemini-embedding-001\").build()).","Verify the merged options chain (request options override model options) isn't replacing a valid model with null/empty."],"exampleFix":"// before\nvar model = GoogleGenAiTextEmbeddingModel.builder().genAiClient(client).build();\n\n// after\nvar model = GoogleGenAiTextEmbeddingModel.builder()\n    .genAiClient(client)\n    .defaultOptions(GoogleGenAiTextEmbeddingOptions.builder().model(\"gemini-embedding-001\").build())\n    .build();","handlingStrategy":"validation","validationCode":"if (!StringUtils.hasText(options.getModel())) {\n    throw new IllegalStateException(\"Configure GoogleGenAiTextEmbeddingOptions.model before calling the embedding model\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set .model(...) in the default options when constructing GoogleGenAiTextEmbeddingModel.","When passing per-request options, re-specify the model to avoid merge surprises.","Add a startup-time assertion that the embedding model name is configured."],"tags":["embedding","configuration","missing-model","validation"],"backgroundTag":"missing-required-option","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}