spring-projects/spring-ai · error · IllegalArgumentException

Image generation failed: image entry missing url and…

Error message

Image generation failed: image entry missing url and b64_json

What it means

Each entry in an OpenAI image response must carry either a url or a b64_json payload. If a native image entry has neither, OpenAiImageModel.call throws this IllegalArgumentException instead of building an Image with null content.

Solutions

  1. Check that your options' responseFormat matches what the selected model returns (b64_json vs url) and set it explicitly.
  2. Log the raw response body to see what fields the API actually returned; a proxy may be stripping url/b64_json.
  3. Catch IllegalArgumentException and retry the generation, treating the response as malformed.

Example fix

ImageGenerateParams params = buildParams();
params = params.toBuilder().responseFormat(ImageGenerateParams.ResponseFormat.B64_JSON).build();
ImageResponse response = imageModel.call(new ImagePrompt(prompt, params));
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return imageModel.call(prompt);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("missing url and b64_json")) {
        throw new MalformedApiResponseException("Image entry had no url or b64_json; check response_format and proxies", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: The images API returns a data entry containing only metadata (e.g. revised_prompt) with neither url nor b64_json set — observed while mapping entries in OpenAiImageModel.call at OpenAiImageModel.java:224.

Common situations: Streaming/partial responses, proxies or gateways stripping fields, API behavior changes for gpt-image-1 vs dall-e models, or a custom response_format the client maps incorrectly.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/8c3ef7d7d20b6776. Report an issue: GitHub.

Appendix: source

Thrown at models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageModel.java:224

					.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext,
							this.observationRegistry)
					.observe(() -> {
						var images = this.openAiClient.images().generate(imageGenerateParams, requestOptions);

						if (images.data().isEmpty() || images.data().get().isEmpty()) {
							throw new IllegalArgumentException("Image generation failed: no image returned");
						}

						List<ImageGeneration> imageGenerations = images.data().get().stream().map(nativeImage -> {
							Image image;
							if (nativeImage.url().isPresent()) {
								image = new Image(nativeImage.url().get(), null);
							}
							else if (nativeImage.b64Json().isPresent()) {
								image = new Image(null, nativeImage.b64Json().get());
							}
							else {
								throw new IllegalArgumentException(
										"Image generation failed: image entry missing url and b64_json");
							}
							var metadata = new OpenAiImageGenerationMetadata(nativeImage.revisedPrompt().orElse(null));
							return new ImageGeneration(image, metadata);
						}).toList();
						ImageResponseMetadata openAiImageResponseMetadata = OpenAiImageResponseMetadata.from(images);
						ImageResponse imageResponse = new ImageResponse(imageGenerations, openAiImageResponseMetadata);
						observationContext.setResponse(imageResponse);
						return imageResponse;
					}));
	}

	/**
	 * Use the provided convention for reporting observation data
	 * @param observationConvention The provided convention
	 */
	public void setObservationConvention(ImageModelObservationConvention observationConvention) {
		Assert.notNull(observationConvention, "observationConvention cannot be null");

View on GitHub (pinned to 98a7beda4f)