spring-projects/spring-ai · error · IllegalArgumentException

URI must not be null or empty

Error message

URI must not be null or empty

What it means

Builder-state validation error thrown when the @McpResource uri attribute is null or empty when building an AbstractMcpResourceMethodCallback. The URI template is required to match client resource requests and extract URI variables.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java:726

		 */
		public T mimeType(String mimeType) {
			this.mimeType = mimeType;
			return (T) this;
		}

		/**
		 * Validate the builder state.
		 * @throws IllegalArgumentException if the builder state is invalid
		 */
		protected void validate() {
			if (this.method == null) {
				throw new IllegalArgumentException("Method must not be null");
			}
			if (this.bean == null) {
				throw new IllegalArgumentException("Bean must not be null");
			}
			if (this.uri == null || this.uri.isEmpty()) {
				throw new IllegalArgumentException("URI must not be null or empty");
			}
			if (this.uriTemplateManagerFactory == null) {
				this.uriTemplateManagerFactory = new DefaultMcpUriTemplateManagerFactory();
			}
			if (this.mimeType == null) {
				this.mimeType = "text/plain";
			}

			if (this.name == null) {
				this.name = this.method.getName();
			}
		}

		/**
		 * Build the callback.
		 * @return A new callback instance
		 */
		public abstract R build();

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Set a non-empty URI template: .uri("docs/{id}") or fill in the @McpResource(uri = ...) value
  2. Validate the annotation value before passing it to the builder
  3. Follow URI template syntax with variables in braces if URI variables are used

Example fix

// before
McpSyncResourceMethodCallback.builder().bean(bean).method(m).uri("").build();
// after
McpSyncResourceMethodCallback.builder().bean(bean).method(m).uri("docs/{id}").build();
Defensive patterns

Strategy: validation

Validate before calling

if (uri == null || uri.isEmpty()) throw new IllegalStateException("@McpResource uri must be a non-empty URI template");

Type guard

if (!(uri instanceof String u) || u.isBlank()) { throw new IllegalStateException("Missing or blank resource uri"); }

Try / catch

try {
    var cb = builder().bean(bean).method(method).uri(uri).build();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("URI must not be null")) throw new IllegalStateException("Set a non-empty uri template on @McpResource", e);
    throw e;
}

Prevention

When it happens

Trigger: Programmatic builder usage omitting .uri(...), or an @McpResource annotation with an empty uri value propagated into the builder.

Common situations: Constructing callbacks manually without the uri; reading the annotation value with reflection and getting an empty string; copy-pasted annotation with blanked-out uri.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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