spring-projects/spring-ai · warning

No sampling methods found

Error message

No sampling methods found

What it means

SyncMcpSamplingProvider.getSamplingSpecifications logs 'No sampling methods found' when annotation scanning of the configured objects produces zero sampling handlers. The provider returns an empty list so the server registers no sampling capability; the warning signals a likely wiring or annotation mistake.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/sampling/SyncMcpSamplingProvider.java:112

				.sorted((m1, m2) -> m1.getName().compareTo(m2.getName()))
				.map(mcpSamplingMethod -> {
					var samplingAnnotation = mcpSamplingMethod.getAnnotation(McpSampling.class);

					Function<CreateMessageRequest, CreateMessageResult> methodCallback = SyncMcpSamplingMethodCallback
						.builder()
						.method(mcpSamplingMethod)
						.bean(samplingObject)
						.sampling(samplingAnnotation)
						.build();

					return new SyncSamplingSpecification(samplingAnnotation.clients(), methodCallback);
				})
				.toList())
			.flatMap(List::stream)
			.toList();

		if (samplingHandlers.isEmpty()) {
			logger.warn("No sampling methods found");
		}
		if (samplingHandlers.size() > 1) {
			if (logger.isWarnEnabled()) {
				logger.warn("Multiple sampling methods found: " + samplingHandlers.size());
			}
		}

		return samplingHandlers;
	}

	/**
	 * 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. Ensure a public @McpSampling-annotated method exists in the objects registered with SyncMcpSamplingProvider.
  2. Verify the constructor receives the correct handler instances (non-empty list).
  3. Confirm visibility and the synchronous signature expected by the scanner.
  4. Remove the sampling provider if sampling is intentionally unsupported.

Example fix

// before
new SyncMcpSamplingProvider(List.of());
// after
new SyncMcpSamplingProvider(List.of(new MySampler())); // with @McpSampling String handle(McpSamplingRequest r) {...}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the sync sampling object before wiring:
boolean hasHandler = Arrays.stream(samplingObject.getClass().getDeclaredMethods())
    .anyMatch(m -> m.isAnnotationPresent(McpSampling.class) && Modifier.isPublic(m.getModifiers()));
if (!hasHandler) throw new IllegalStateException("Missing public @McpSampling method in " + samplingObject);

Prevention

When it happens

Trigger: Objects passed to SyncMcpSamplingProvider contain no public @McpSampling methods, methods are non-public or have unsupported signatures, or the objects list is empty — empty samplingHandlers triggers the warn at SyncMcpSamplingProvider.java:112.

Common situations: Sampling handler defined but never handed to the provider; annotation removed or renamed during an upgrade; handler method private; async-style handler supplied to the sync 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/8b2b9e58186cdd7a. Report an issue: GitHub.