spring-projects/spring-ai · error · IllegalArgumentException

Request must not be null

Error message

Request must not be null

What it means

Thrown by SyncMcpElicitationMethodCallback.apply(ElicitRequest) when the caller passes a null request. The callback reflects the request into the handler method's single ElicitRequest parameter, so a null argument would cause an NPE downstream; it fails fast with this message.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/elicitation/SyncMcpElicitationMethodCallback.java:61

	private SyncMcpElicitationMethodCallback(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 elicitation request, must not be null
	 * @return The result of the method invocation
	 * @throws McpElicitationMethodException if there is an error invoking the elicitation
	 * method
	 * @throws IllegalArgumentException if the request is null
	 */
	@Override
	public ElicitResult apply(ElicitRequest 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);

			if (this.method.getReturnType().isAssignableFrom(StructuredElicitResult.class)) {
				StructuredElicitResult<?> structuredElicitResult = (StructuredElicitResult<?>) result;
				var content = structuredElicitResult.structuredContent() != null
						? jsonHelper.convertToMap(structuredElicitResult.structuredContent()) : null;

				return ElicitResult.builder(structuredElicitResult.action())
					.content(content)
					.meta(structuredElicitResult.meta())

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Never call apply(null); construct a valid McpSchema.ElicitRequest with its params/meta
  2. Guard the call site: only invoke the callback when the incoming MCP elicitation request is present
  3. Catch IllegalArgumentException around apply() if null inputs are possible from untrusted wiring and convert to a proper error response

Example fix

// before
ElicitResult result = callback.apply(null);

// after
if (incoming != null) {
    ElicitResult result = callback.apply(incoming);
}
Defensive patterns

Strategy: validation

Validate before calling

if (request == null) {
    throw new IllegalStateException("No elicitation request received; refusing to invoke handler");
}
ElicitResult result = callback.apply(request);

Type guard

boolean hasRequest(ElicitRequest req) { return req != null; }

Try / catch

try {
    return callback.apply(request);
} catch (IllegalArgumentException e) {
    return new ElicitResult(ElicitResult.Action.DECLINE, Map.of());
}

Prevention

When it happens

Trigger: Invoking the elicitation function manually with null: elicitationHandler.apply(null) — e.g. a test harness or a custom client wiring that forwards a missing elicitation payload.

Common situations: Unit tests exercising the callback (as seen by the testNullRequest caller), or a client adapter that doesn't check whether the incoming elicitation message carries a request before invoking the handler.

Related errors


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