spring-projects/spring-ai · warning

No async complete methods found in the provided complete obj

Error message

No async complete methods found in the provided complete objects: <completeObjects>

What it means

AsyncMcpCompleteProvider.getCompleteSpecifications() scans the supplied completion provider objects for methods annotated as completion handlers (e.g. @McpComplete). If none of the objects expose a matching async complete method, an empty specification list results and this warning is logged. The provider is built with zero completions, so completion requests will find nothing.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/complete/AsyncMcpCompleteProvider.java:90

					var completeRef = CompleteAdapter.asCompleteReference(completeAnnotation, mcpCompleteMethod);

					var methodCallback = AsyncMcpCompleteMethodCallback.builder()
						.method(mcpCompleteMethod)
						.bean(completeObject)
						.prompt(completeAnnotation.prompt().isEmpty() ? null : completeAnnotation.prompt())
						.uri(completeAnnotation.uri().isEmpty() ? null : completeAnnotation.uri())
						.build();

					return new AsyncCompletionSpecification(completeRef, methodCallback);
				})
				.toList())
			.flatMap(List::stream)
			.toList();

		if (asyncCompleteSpecification.isEmpty()) {
			if (logger.isWarnEnabled()) {
				logger
					.warn("No async complete methods found in the provided complete objects: " + this.completeObjects);
			}
		}

		return asyncCompleteSpecification;
	}

	/**
	 * Returns the methods of the given bean class.
	 * @param bean the bean instance
	 * @return the methods of the bean class
	 */
	protected Method[] doGetClassMethods(Object bean) {
		return bean.getClass().getDeclaredMethods();
	}

}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Annotate at least one method in each complete object with @McpComplete and verify the import is org.springframework.ai.mcp.annotation.*
  2. Verify the method signature matches what the provider scans for (prompt-name argument plus completion String argument) and uses reactive return types for the async provider
  3. Check the log/scan setup so the annotated object is actually passed to the provider (not a different instance/class)

Example fix

// before
public class MyCompletes { public List<String> complete(String prefix) { return List.of(prefix + "!"); } }
// after
public class MyCompletes {
  @McpComplete(prompt = "my-prompt")
  public Mono<List<String>> complete(String prefix) { return Mono.just(List.of(prefix + "!")); }
}
Defensive patterns

Strategy: validation

Validate before calling

boolean hasComplete = java.util.Arrays.stream(completeObject.getClass().getDeclaredMethods())
  .anyMatch(m -> m.isAnnotationPresent(McpComplete.class));
if (!hasComplete) {
  throw new IllegalStateException("Complete object " + completeObject + " has no @McpComplete methods");
}

Type guard

static boolean hasAnnotatedCompleteMethods(Object o) {
  return java.util.Arrays.stream(o.getClass().getDeclaredMethods())
    .anyMatch(m -> m.isAnnotationPresent(McpComplete.class));
}

Prevention

When it happens

Trigger: Registering complete objects with the async completion provider where no method carries the completion annotation, the annotation is misplaced (wrong package/import), or the method signature does not match the expected complete shape.

Common situations: Typos or wrong @McpComplete import (e.g. from another library); methods returning reactive types scanned by a sync scanner or vice versa; forgetting the annotation entirely while passing a plain object as a complete provider.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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