{"record":{"id":"8537b2d05e741b3f","repo":"spring-projects/spring-ai","slug":"imageprompt-must-contain-at-least-one-non-empty-me","errorCode":null,"errorMessage":"ImagePrompt must contain at least one non-empty message","messagePattern":"ImagePrompt must contain at least one non-empty message","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-google-genai-image/src/main/java/org/springframework/ai/google/genai/image/GoogleGenAiImageModel.java","lineNumber":145,"sourceCode":"\t\t\t\tfinal GoogleGenAiImageOptions options = (GoogleGenAiImageOptions) imagePrompt.getOptions();\n\t\t\t\tAssert.notNull(options, \"Options must not be null\");\n\n\t\t\t\tfinal String model = options.getModel();\n\t\t\t\tAssert.notNull(model, \"Model must not be null\");\n\n\t\t\t\tfinal String modelName = this.connectionDetails.getModelEndpointName(model);\n\n\t\t\t\tfinal GenerateContentConfig config = getGenerateContentConfig(options);\n\n\t\t\t\tfinal List<Content> contents = imagePrompt.getInstructions()\n\t\t\t\t\t.stream()\n\t\t\t\t\t.map(GoogleGenAiImageModel::messageToParts)\n\t\t\t\t\t.filter(Predicate.not(List::isEmpty))\n\t\t\t\t\t.map(parts -> Content.builder().role(MessageType.USER.getValue()).parts(parts).build())\n\t\t\t\t\t.toList();\n\n\t\t\t\tif (contents.isEmpty()) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"ImagePrompt must contain at least one non-empty message\");\n\t\t\t\t}\n\n\t\t\t\tfinal GenerateContentResponse imagesResponse = RetryUtils.execute(this.retryTemplate,\n\t\t\t\t\t\t() -> this.genAiClient.models.generateContent(modelName, contents, config));\n\n\t\t\t\tfinal List<Candidate> candidates = Optional.ofNullable(imagesResponse)\n\t\t\t\t\t.map(GenerateContentResponse::candidates)\n\t\t\t\t\t.flatMap(Function.identity())\n\t\t\t\t\t.orElse(List.of());\n\n\t\t\t\tfinal List<ImageGeneration> generationList = candidates.stream()\n\t\t\t\t\t.flatMap(GoogleGenAiImageModel::candidateToImageGenerations)\n\t\t\t\t\t.toList();\n\n\t\t\t\tfinal List<String> candidateTexts = candidates.stream()\n\t\t\t\t\t.flatMap(candidate -> candidate.content().flatMap(Content::parts).orElse(List.of()).stream())\n\t\t\t\t\t.filter(part -> part.inlineData().isEmpty())\n\t\t\t\t\t.map(Part::text)","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-google-genai-image/src/main/java/org/springframework/ai/google/genai/image/GoogleGenAiImageModel.java#L127-L163","documentation":"GoogleGenAiImageModel.call() converts each message in the ImagePrompt into Gemini Content objects with parts, filtering out messages that produce no parts (e.g. no text and no media). If no message yields any parts, there is no usable prompt to send to generateContent, so it throws this IllegalArgumentException.","triggerScenarios":"Calling call(new ImagePrompt(\"\")) or an ImagePrompt whose messages contain only empty strings / blank instructions — every message maps to an empty parts list and 'contents' ends up empty.","commonSituations":"Template-rendered prompts that resolved to an empty string (missing template variables); user input passed through unvalidated and blank; a refactor passing instructions as empty lists; whitespace-only prompts from form submissions.","solutions":["Validate the prompt before calling: ensure the ImagePrompt contains at least one message with non-blank text or media.","Fix template/user-input handling so blank prompts are rejected or filled earlier.","Wrap the call in a guard that throws a more descriptive application-level error for empty prompts."],"exampleFix":"// before\nImageResponse res = imageModel.call(new ImagePrompt(userInput));\n\n// after\nif (!StringUtils.hasText(userInput)) {\n    throw new IllegalArgumentException(\"Image prompt text must not be blank\");\n}\nImageResponse res = imageModel.call(new ImagePrompt(userInput));","handlingStrategy":"validation","validationCode":"boolean hasPrompt = prompt.getInstructions().stream()\n    .anyMatch(m -> StringUtils.hasText(m.getText()) || (m.getMedia() != null && !m.getMedia().isEmpty()));\nif (!hasPrompt) { throw new IllegalArgumentException(\"ImagePrompt is empty\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate user/template-derived prompt text for blankness before image generation.","Check template variable rendering so prompts never resolve to empty strings.","Add tests for empty and whitespace-only prompts."],"tags":["image-generation","validation","empty-input","illegal-argument"],"backgroundTag":"empty-required-field","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"}