spring-projects/spring-ai · error · IllegalArgumentException

Method must have exactly 1 parameter…

Error message

Method must have exactly 1 parameter (List<McpSchema.Prompt>): 

What it means

validateParameters enforces that a prompt-list-changed handler method takes exactly one parameter of type List<McpSchema.Prompt>. A method with any other parameter count cannot receive the changed prompt list and is rejected at registration time with this IllegalArgumentException.

Solutions

  1. Change the handler signature to exactly one parameter: void handler(List<McpSchema.Prompt> prompts)
  2. Remove extra parameters and obtain needed services via injection/fields instead of method parameters
  3. Read the callback API docs: only the List<Prompt> is passed to the handler

Example fix

// before
public void onPromptListChanged() { ... }
// after
public void onPromptListChanged(List<McpSchema.Prompt> prompts) { ... }
Defensive patterns

Strategy: validation

Validate before calling

if (method.getParameterCount() != 1 || !List.class.isAssignableFrom(method.getParameterTypes()[0])) { throw new IllegalArgumentException("Handler must take exactly one List<McpSchema.Prompt>"); }

Type guard

boolean isValidHandler = m.getParameterCount() == 1 && List.class.isAssignableFrom(m.getParameterTypes()[0]);

Try / catch

try { server.addListChangedHandler(callback); } catch (IllegalArgumentException e) { throw new ConfigurationException("Invalid prompt list changed handler: " + e.getMessage(), e); }

Prevention

When it happens

Trigger: Registering a prompt-list-changed callback whose method has 0 parameters or more than 1 parameter (e.g. no-arg handlers or handlers taking extra context arguments).

Common situations: Developers write no-argument notification handlers assuming notifications carry no data, or add extra parameters (server exchange, session) by analogy with tool callbacks.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

	 * Validates that the method return type is compatible with the prompt list changed
	 * consumer callback. This method should be implemented by subclasses to handle
	 * specific return type validation.
	 * @param method The method to validate
	 * @throws IllegalArgumentException if the return type is not compatible
	 */
	protected abstract void validateReturnType(Method method);

	/**
	 * Validates method parameters. This method provides common validation logic.
	 * @param method The method to validate
	 * @throws IllegalArgumentException if the parameters are not compatible
	 */
	protected void validateParameters(Method method) {
		Parameter[] parameters = method.getParameters();

		// Check parameter count - must have exactly 1 parameter
		if (parameters.length != 1) {
			throw new IllegalArgumentException(
					"Method must have exactly 1 parameter (List<McpSchema.Prompt>): " + method.getName() + " in "
							+ method.getDeclaringClass().getName() + " has " + parameters.length + " parameters");
		}

		// Check parameter type - must be List<McpSchema.Prompt>
		Class<?> paramType = parameters[0].getType();
		if (!List.class.isAssignableFrom(paramType)) {
			throw new IllegalArgumentException("Parameter must be of type List<McpSchema.Prompt>: " + method.getName()
					+ " in " + method.getDeclaringClass().getName() + " has parameter of type " + paramType.getName());
		}
	}

	/**
	 * Builds the arguments array for invoking the method.
	 * <p>
	 * This method constructs an array of arguments based on the method's parameter types
	 * and the available values.
	 * @param method The method to build arguments for

View on GitHub (pinned to 98a7beda4f)