spring-projects/spring-ai · error · IllegalArgumentException

Request must not be null

Error message

Request must not be null

What it means

SyncMcpSamplingMethodCallback.apply() throws IllegalArgumentException when invoked with a null CreateMessageRequest. The callback immediately dereferences the request to build method arguments, so a null request is rejected up front with a clear message rather than a downstream NPE.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/sampling/SyncMcpSamplingMethodCallback.java:57

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

	/**
	 * Apply the callback to the given request.
	 * <p>
	 * This method builds the arguments for the method call, invokes the method, and
	 * returns the result.
	 * @param request The sampling request, must not be null
	 * @return The result of the method invocation
	 * @throws McpSamplingMethodException if there is an error invoking the sampling
	 * method
	 * @throws IllegalArgumentException if the request is null
	 */
	@Override
	public CreateMessageResult apply(CreateMessageRequest request) {
		if (request == null) {
			throw new IllegalArgumentException("Request must not be null");
		}

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

			// Invoke the method
			this.method.setAccessible(true);
			Object result = this.method.invoke(this.bean, args);

			// Return the result
			return (CreateMessageResult) result;
		}
		catch (Exception e) {
			throw new McpSamplingMethodException("Error invoking sampling method: " + this.method.getName(), e);
		}
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Never call apply() manually with null; only invoke via the framework's sampling dispatch
  2. In custom code, assert request != null before calling apply
  3. If a test intentionally passes null, expect IllegalArgumentException and assert it

Example fix

// before
CreateMessageResult r = callback.apply(null);
// after
if (request == null) {
    throw new IllegalArgumentException("request required");
}
CreateMessageResult r = callback.apply(request);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(request, "CreateMessageRequest must not be null");
CreateMessageResult result = callback.apply(request);

Try / catch

try { result = callback.apply(request); } catch (IllegalArgumentException e) { handleMissingRequest(e); }

Prevention

When it happens

Trigger: Calling callback.apply(null) directly in unit tests or custom dispatch code; a transport layer passing a null request into the sampling handler chain.

Common situations: Hand-written tests probing callback behavior (e.g. testNullRequest); custom MCP server code invoking the callback outside the normal framework dispatch where requests are guaranteed non-null.

Related errors


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