spring-projects/spring-ai · error · McpPromptListChangedConsumerMethodException

Error invoking prompt list changed consumer method:

Error message

Error invoking prompt list changed consumer method: 

What it means

A McpPromptListChangedConsumerMethodException wrapping the underlying failure, thrown by SyncMcpPromptListChangedMethodCallback.accept() when the reflective this.method.invoke(bean, args) call fails. Any exception raised inside the user's handler method (or by argument building/IllegalAccess) is wrapped, with the handler method name in the message and the original cause attached.

Source

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

	 * 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
	 * consumer callback.
	 * @param method The method to validate
	 * @throws IllegalArgumentException if the return type is not compatible
	 */
	@Override
	protected void validateReturnType(Method method) {
		Class<?> returnType = method.getReturnType();

		if (returnType != void.class) {
			throw new IllegalArgumentException("Method must have void return type: " + method.getName() + " in "
					+ method.getDeclaringClass().getName() + " returns " + returnType.getName());
		}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Inspect getCause() of the McpPromptListChangedConsumerMethodException — the real fix belongs to the wrapped exception.
  2. Match the handler signature exactly to the expected consumer shape, e.g. void handler(List<McpSchema.Prompt> prompts).
  3. Fix the bug in the handler body (null checks, downstream calls) that caused the wrapped exception.
  4. For JPMS access errors, open the package (–add-opens) or keep handler methods in an exported/open package.

Example fix

// before (signature mismatch -> reflective invoke fails)
public void onPromptsChanged(PromptListChangedNotification n) { ... }
// after
public void onPromptsChanged(List<McpSchema.Prompt> updatedPrompts) { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

Method m = bean.getClass().getMethod("onPromptsChanged", List.class);
// parameter type check before wiring
if (!List.class.isAssignableFrom(m.getParameterTypes()[0])) {
    throw new IllegalStateException("handler must accept List<McpSchema.Prompt>");
}

Try / catch

try {
    callback.accept(updatedPrompts);
} catch (McpPromptListChangedConsumerMethodException e) {
    Throwable cause = e.getCause();
    log.error("Prompt list changed handler {} failed: {}", e.getMessage(), cause, cause);
    // handle or rethrow based on cause type
}

Prevention

When it happens

Trigger: The handler method throws at runtime (NPE, repository failure, etc.); the method's parameter types do not match the built arguments (IllegalArgumentException from reflection); the method is not accessible and setAccessible fails under a SecurityManager/JPMS strong encapsulation.

Common situations: Handler signature drift — declaring the consumer with wrong parameter types after an MCP SDK upgrade; handler code throwing due to downstream service failures; Java 16+ module encapsulation blocking setAccessible on non-exported classes.

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/9011043dad7f084f. Report an issue: GitHub.