spring-projects/spring-ai · error · IllegalArgumentException

Updated prompts list must not be null

Error message

Updated prompts list must not be null

What it means

IllegalArgumentException thrown by SyncMcpPromptListChangedMethodCallback.accept(List<McpSchema.Prompt>) when the incoming updatedPrompts list is null. The callback forwards the prompt list to the user's consumer method; a null list cannot be mapped to a valid method argument, so it is rejected before reflective invocation.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/prompt/SyncMcpPromptListChangedMethodCallback.java:56

		implements Consumer<List<McpSchema.Prompt>> {

	private SyncMcpPromptListChangedMethodCallback(Builder builder) {
		super(builder.method, builder.bean);
	}

	/**
	 * Accept the prompt list change notification and process it.
	 * <p>
	 * This method builds the arguments for the method call and invokes the method.
	 * @param updatedPrompts The updated list of prompts, must not be null
	 * @throws McpPromptListChangedConsumerMethodException if there is an error invoking
	 * the prompt list changed consumer method
	 * @throws IllegalArgumentException if the updatedPrompts is null
	 */
	@Override
	public void accept(List<McpSchema.Prompt> updatedPrompts) {
		if (updatedPrompts == null) {
			throw new IllegalArgumentException("Updated prompts list must not be null");
		}

		try {
			// Build arguments for the method call
			Object[] args = this.buildArgs(this.method, null, updatedPrompts);

			// Invoke the method
			this.method.setAccessible(true);
			this.method.invoke(this.bean, args);
		}
		catch (Exception e) {
			throw new McpPromptListChangedConsumerMethodException(
					"Error invoking prompt list changed consumer method: " + this.method.getName(), e);
		}
	}

	/**
	 * Validates that the method return type is compatible with the prompt list changed

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Fix the caller so it passes an empty list (List.of()) instead of null when no prompts exist.
  2. If you invoke the callback manually (e.g. in tests), pass List.of() rather than null.
  3. If this comes from deserialization of the notification, check client/server version compatibility of the MCP schema.

Example fix

// before
callback.accept(null);
// after
callback.accept(List.of());
Defensive patterns

Strategy: validation

Validate before calling

if (updatedPrompts == null) {
    updatedPrompts = List.of();
}
callback.accept(updatedPrompts);

Type guard

static List<McpSchema.Prompt> nullSafe(List<McpSchema.Prompt> prompts) {
    return prompts != null ? prompts : List.of();
}

Try / catch

try {
    callback.accept(updatedPrompts);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Updated prompts list must not be null")) {
        log.warn("Null prompt list notification — substituting empty list");
        callback.accept(List.of());
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: The MCP server/framework invoking accept(null) — typically when a prompts/list_changed notification carries no parseable prompt list or a caller passes null directly to the callback. Not caused by user handler code itself.

Common situations: Custom or wrapped MCP client plumbing passing null notifications; tests calling accept(null) directly; version mismatches where the notification payload shape changed and deserialization yielded null.

Related errors


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