spring-projects/spring-ai · error · IllegalArgumentException

Only one of prompt or uri can be provided in McpComplete ann

Error message

Only one of prompt or uri can be provided in McpComplete annotation

What it means

CompleteAdapter.asCompleteReference enforces the MCP rule that a completion reference names exactly one target: a prompt OR a resource URI, never both. This error is thrown when the McpComplete annotation has both a non-empty prompt and a non-empty uri.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/adapter/CompleteAdapter.java:55

	/**
	 * Convert a McpComplete annotation to a McpSchema.CompleteReference object.
	 * @param mcpComplete The McpComplete annotation
	 * @return The corresponding McpSchema.CompleteReference object
	 * @throws IllegalArgumentException if neither prompt nor uri is provided, or if both
	 * are provided
	 */
	public static McpSchema.CompleteReference asCompleteReference(McpComplete mcpComplete) {
		Assert.notNull(mcpComplete, "mcpComplete cannot be null");

		String prompt = mcpComplete.prompt();
		String uri = mcpComplete.uri();

		// Validate that either prompt or uri is provided, but not both
		if ((prompt == null || prompt.isEmpty()) && (uri == null || uri.isEmpty())) {
			throw new IllegalArgumentException("Either prompt or uri must be provided in McpComplete annotation");
		}
		if ((prompt != null && !prompt.isEmpty()) && (uri != null && !uri.isEmpty())) {
			throw new IllegalArgumentException("Only one of prompt or uri can be provided in McpComplete annotation");
		}

		// Create the appropriate reference type based on what's provided
		if (prompt != null && !prompt.isEmpty()) {
			return McpSchema.PromptReference.builder(prompt).build();
		}
		else {
			return new McpSchema.ResourceReference(uri);
		}
	}

	/**
	 * Convert a McpComplete annotation and Method to a McpSchema.CompleteReference
	 * object.
	 * @param mcpComplete The McpComplete annotation
	 * @param method The method annotated with McpComplete
	 * @return The corresponding McpSchema.CompleteReference object
	 * @throws IllegalArgumentException if neither prompt nor uri is provided, or if both

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Remove the uri attribute if the completion targets a prompt
  2. Remove the prompt attribute if the completion targets a resource URI
  3. Split into two separate @McpComplete annotations, one per target

Example fix

// before
@McpComplete(prompt = "code-review", uri = "file:///logs/{path}")
public List<String> complete(String argument) { ... }

// after
@McpComplete(prompt = "code-review")
public List<String> complete(String argument) { ... }
Defensive patterns

Strategy: validation

Validate before calling

boolean promptSet = ann.prompt() != null && !ann.prompt().isEmpty();
boolean uriSet = ann.uri() != null && !ann.uri().isEmpty();
if (promptSet && uriSet) {
    throw new IllegalStateException("@McpComplete allows only one of prompt or uri");
}

Prevention

When it happens

Trigger: Calling asCompleteReference on an @McpComplete annotation where both prompt() and uri() return non-empty values, e.g. @McpComplete(prompt = "x", uri = "file:///y").

Common situations: Copy-pasting an annotation example that had uri and adding prompt for a different use; IDE auto-completing both attributes; merging code from two branches each setting a different attribute.

Related errors


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