spring-projects/spring-ai · error · IllegalArgumentException

Request must not be null

Error message

Request must not be null

What it means

SyncStatelessMcpCompleteMethodCallback.apply throws this IllegalArgumentException when the CompleteRequest passed to the callback is null. The stateless completion callback requires a non-null request to extract the argument value being completed.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/SyncStatelessMcpCompleteMethodCallback.java:65

		this.validateMethod(this.method);
	}

	/**
	 * Apply the callback to the given context and request.
	 * <p>
	 * This method builds the arguments for the method call, invokes the method, and
	 * converts the result to a CompleteResult.
	 * @param context The transport context, may be null if the method doesn't require it
	 * @param request The complete request, must not be null
	 * @return The complete result
	 * @throws McpCompleteMethodException if there is an error invoking the complete
	 * method
	 * @throws IllegalArgumentException if the request is null
	 */
	@Override
	public CompleteResult apply(McpTransportContext context, CompleteRequest 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, context, request);

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

			// Convert the result to a CompleteResult
			return convertToCompleteResult(result);
		}
		catch (Exception e) {
			throw new McpCompleteMethodException("Error invoking complete method: " + this.method.getName(), e);
		}
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Always pass a constructed CompleteRequest (with its CompleteRequestArgument) to apply()
  2. Add a null check in caller code before invoking the callback
  3. If building requests manually in tests, use a representative instance like new CompleteRequest(new CompleteRequestArgument("val"))

Example fix

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

Strategy: validation

Validate before calling

if (request == null)
    throw new IllegalArgumentException("CompleteRequest is required before invoking the callback");

Type guard

static boolean hasRequest(CompleteRequest r) { return r != null && r.argument() != null; }

Try / catch

try { return callback.apply(context, request); }
catch (IllegalArgumentException e) { log.error("null completion request: {}", e.getMessage()); return new CompleteResult(new CompleteCompletion(List.of(), 0, false)); }

Prevention

When it happens

Trigger: Registering or invoking the callback programmatically and passing null as the CompleteRequest, or a transport/adapter layer that forwards a missing payload as null instead of a default request.

Common situations: Custom McpSyncServer wiring where the completion handler is called directly in unit tests or integration glue with a null request; framework-bridging code that does not guard against absent parameters.

Related errors


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