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

  1. Pass at least one valid, non-blank client Id in the clients array.
  2. Filter blank entries from the config-derived list before constructing the specification.
  3. 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

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


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)