spring-projects/spring-ai · error · java.lang.IllegalArgumentException

Method must return either GetPromptResult, List

Error message

Method must return either GetPromptResult, List<PromptMessage>, List<String>, PromptMessage, String, or Mono<T>: {method.getName()} in {method.getDeclaringClass().getName()} returns {returnType.getName()}

What it means

AsyncStatelessMcpPromptMethodCallback validates that the prompt method returns one of GetPromptResult, List (e.g. List<PromptMessage> or List<String>), PromptMessage, String, or a Mono of any of these. Any other return type is rejected with IllegalArgumentException because the callback cannot convert it into a prompt response.

Solutions

  1. Change the return type to one of GetPromptResult, List<PromptMessage>, List<String>, PromptMessage, String, or Mono<T> of those
  2. Map your custom result into a GetPromptResult or PromptMessage before returning
  3. Convert CompletableFuture to Mono using Mono.fromFuture(...)

Example fix

// before
@McpPrompt(description = "p")
public MyResult p(Request req) {...}
// after
@McpPrompt(description = "p")
public Mono<GetPromptResult> p(Request req) { return Mono.just(new GetPromptResult(description)); }
Defensive patterns

Strategy: validation

Validate before calling

Set<Class<?>> ok = Set.of(GetPromptResult.class, List.class, PromptMessage.class, String.class, Mono.class); if (ok.stream().noneMatch(c -> c.isAssignableFrom(method.getReturnType()))) throw new IllegalStateException("bad return type");

Try / catch

try { server.addPrompt(cb); } catch (IllegalArgumentException e) { /* fix return type */ }

Prevention

When it happens

Trigger: Registering an @McpPrompt method whose return type is a POJO, Map, CompletableFuture, or other non-supported type while using the async stateless callback.

Common situations: Returning custom domain objects from prompt methods; forgetting to map a domain object to GetPromptResult/PromptMessage; using CompletableFuture instead of Mono.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/AsyncStatelessMcpPromptMethodCallback.java:156

			}
		});
	}

	@Override
	protected boolean isSupportedExchangeOrContextType(Class<?> paramType) {
		return McpTransportContext.class.isAssignableFrom(paramType);
	}

	@Override
	protected void validateReturnType(Method method) {
		Class<?> returnType = method.getReturnType();

		boolean validReturnType = GetPromptResult.class.isAssignableFrom(returnType)
				|| List.class.isAssignableFrom(returnType) || PromptMessage.class.isAssignableFrom(returnType)
				|| String.class.isAssignableFrom(returnType) || Mono.class.isAssignableFrom(returnType);

		if (!validReturnType) {
			throw new IllegalArgumentException("Method must return either GetPromptResult, List<PromptMessage>, "
					+ "List<String>, PromptMessage, String, or Mono<T>: " + method.getName() + " in "
					+ method.getDeclaringClass().getName() + " returns " + returnType.getName());
		}
	}

	/**
	 * Create a new builder.
	 * @return A new builder instance
	 */
	public static Builder builder() {
		return new Builder();
	}

	/**
	 * Builder for creating AsyncStatelessMcpPromptMethodCallback instances.
	 * <p>
	 * This builder provides a fluent API for constructing
	 * AsyncStatelessMcpPromptMethodCallback instances with the required parameters.

View on GitHub (pinned to 98a7beda4f)