spring-projects/spring-ai · error · IllegalArgumentException

model cannot be null or empty

Error message

model cannot be null or empty

What it means

OllamaChatModel.verifyPromptChatOptions() validates the runtime options attached to a Prompt. Ollama requires an explicit model name, so if ChatOptions is present but its model is null or empty, IllegalArgumentException('model cannot be null or empty') is thrown before any HTTP call.

Source

Thrown at models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java:364

				var generator = new Generation(assistantMessage, generationMetadata);
				return new ChatResponse(List.of(generator), from(chunk, previousChatResponse));
			});

			Flux<ChatResponse> chatResponseFlux = chatResponse.flatMap(response -> Flux.just(response))
				.doOnError(observation::error)
				.doFinally(s -> observation.stop())
				.contextWrite(ctx -> ctx.put(ObservationThreadLocalAccessor.KEY, observation));

			return new MessageAggregator().aggregate(chatResponseFlux, observationContext::setResponse);
		});
	}

	private void verifyPromptChatOptions(Prompt prompt) {
		var chatOptions = prompt.getOptions();

		if (chatOptions != null && !StringUtils.hasText(chatOptions.getModel())) {
			throw new IllegalArgumentException("model cannot be null or empty");
		}
	}

	/**
	 * Package access for testing.
	 */
	OllamaApi.ChatRequest ollamaChatRequest(Prompt prompt, boolean stream) {

		List<OllamaApi.Message> ollamaMessages = prompt.getInstructions().stream().map(message -> {
			if (message.getMessageType() == MessageType.SYSTEM) {
				return List.of(OllamaApi.Message.builder(Role.SYSTEM).content(message.getText()).build());
			}
			else if (message.getMessageType() == MessageType.USER) {
				var messageBuilder = OllamaApi.Message.builder(Role.USER).content(message.getText());
				if (message instanceof UserMessage userMessage) {
					if (!CollectionUtils.isEmpty(userMessage.getMedia())) {
						messageBuilder.images(userMessage.getMedia()
							.stream()

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Set a default model when constructing the model: OllamaOptions.builder().model("llama3").build().
  2. Or set the model on the per-request options passed into the Prompt.
  3. Check option-merging code for accidental nulling of the model field.

Example fix

// before
OllamaChatModel.builder().ollamaApi(api).build(); // no default model
// after
OllamaChatModel.builder().ollamaApi(api)
    .defaultOptions(OllamaOptions.builder().model("llama3").build()).build();
Defensive patterns

Strategy: validation

Validate before calling

var options = prompt.getOptions();
if (options != null && (options.getModel() == null || options.getModel().isBlank())) {
    throw new IllegalArgumentException("Set model via OllamaOptions or defaultOptions");
}

Type guard

boolean hasModel(OllamaChatOptions o) { return o != null && o.getModel() != null && !o.getModel().isBlank(); }

Try / catch

try {
    return ollamaChatModel.call(prompt);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("model cannot be null")) { /* set default model options and retry */ }
    throw e;
}

Prevention

When it happens

Trigger: Calling call()/stream() with a Prompt whose OllamaChatOptions has no model set and no default model was configured on the OllamaChatModel builder.

Common situations: Building OllamaChatModel without .defaultOptions(OllamaOptions.builder().model(...).build()) and then passing runtime options without a model; copying options between requests and dropping the model field.

Understand the failure class

Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.

Related errors


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