spring-projects/spring-ai · error · java.lang.IllegalArgumentException
At least one client Id must be specified
Error message
At least one client Id must be specified
What it means
The AsyncProgressSpecification record requires a non-empty clients array with no blank entries, since progress notifications must be addressed to at least one specific client Id. The compact constructor throws IllegalArgumentException when clients is empty, or when any element is null/blank after trimming.
Solutions
- Pass at least one valid, non-blank client Id in the clients array.
- Filter blank entries from the config-derived list before constructing the specification.
- If broadcast to all clients is intended, enumerate the known client Ids explicitly (this API has no wildcard).
Example fix
// before
new AsyncProgressSpecification(new String[]{}, handler);
// after
new AsyncProgressSpecification(new String[]{"client-1"}, handler); Defensive patterns
Strategy: validation
Validate before calling
String[] clients = configClients == null ? new String[0]
: Arrays.stream(configClients).map(String::trim).filter(s -> !s.isEmpty()).toArray(String[]::new);
if (clients.length == 0) throw new IllegalStateException("Configure at least one client Id for progress notifications");
var spec = new AsyncProgressSpecification(clients, handler); Type guard
function validClients(arr) {
return Array.isArray(arr) && arr.length > 0 && arr.every(c => typeof c === 'string' && c.trim().length > 0);
} Try / catch
try {
return new AsyncProgressSpecification(rawClients, handler);
} catch (IllegalArgumentException e) {
if ("At least one client Id must be specified".equals(e.getMessage())) {
throw new ConfigurationException("clients property is missing or blank — set mcp progress client ids", e);
}
throw e;
} Prevention
- Trim and filter whitespace entries when splitting client lists from config strings.
- Provide application properties defaults for progress client ids.
- Validate configuration at startup before building specifications.
When it happens
Trigger: Constructing new AsyncProgressSpecification(new String[0], handler), new AsyncProgressSpecification(new String[]{"", " "}, handler), or new AsyncProgressSpecification(null, handler) (the latter triggers the null message instead).
Common situations: Building client lists dynamically from configuration where the property is missing or empty; forgetting to fill a defaults list; whitespace-only entries from comma-split config strings.
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
- Asynchronous progress methods must return void or Mono
- Bean must not be null
- Bean must not be null
- clients must not be empty
- clients must not be empty
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/cefbc34919950fbc.
Report an issue: GitHub.
Appendix: source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/progress/AsyncProgressSpecification.java:37
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Function;
import io.modelcontextprotocol.spec.McpSchema.ProgressNotification;
import reactor.core.publisher.Mono;
/**
* Specification for asynchronous progress handlers.
*
* @param clients The client IDs for the progress handler
* @param progressHandler The function that handles progress notifications asynchronously
* @author Christian Tzolov
*/
public record AsyncProgressSpecification(String[] clients, Function<ProgressNotification, Mono<Void>> progressHandler) {
public AsyncProgressSpecification {
Objects.requireNonNull(clients, "clients must not be null");
if (clients.length == 0 || Arrays.stream(clients).map(String::trim).anyMatch(String::isEmpty)) {
throw new IllegalArgumentException("At least one client Id must be specified");
}
Objects.requireNonNull(progressHandler, "progressHandler must not be null");
}
}
View on GitHub (pinned to 98a7beda4f)