{"record":{"id":"b9b81ee6e9575878","repo":"spring-projects/spring-ai","slug":"clients-must-not-be-empty-b9b81e","errorCode":null,"errorMessage":"clients must not be empty","messagePattern":"clients must not be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/logging/AsyncLoggingSpecification.java","lineNumber":32,"sourceCode":" * limitations under the License.\n */\n\npackage org.springframework.ai.mcp.annotation.method.logging;\n\nimport java.util.Arrays;\nimport java.util.Objects;\nimport java.util.function.Function;\n\nimport io.modelcontextprotocol.spec.McpSchema.LoggingMessageNotification;\nimport reactor.core.publisher.Mono;\n\npublic record AsyncLoggingSpecification(String[] clients,\n\t\tFunction<LoggingMessageNotification, Mono<Void>> loggingHandler) {\n\n\tpublic AsyncLoggingSpecification {\n\t\tObjects.requireNonNull(clients, \"clients must not be null\");\n\t\tif (clients.length == 0 || Arrays.stream(clients).anyMatch(String::isEmpty)) {\n\t\t\tthrow new IllegalArgumentException(\"clients must not be empty\");\n\t\t}\n\t\tObjects.requireNonNull(loggingHandler, \"loggingHandler must not be null\");\n\t}\n\n}\n","sourceCodeStart":14,"sourceCodeEnd":38,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/logging/AsyncLoggingSpecification.java#L14-L38","documentation":"The AsyncLoggingSpecification record is a compact-constructor validation for an async MCP logging registration. The clients array must be non-null, non-empty, and contain no empty strings; otherwise an IllegalArgumentException is thrown at construction time. This fails fast so invalid logging registrations are caught before they are wired into an MCP server.","triggerScenarios":"Calling new AsyncLoggingSpecification(new String[0], handler), passing null clients, or passing an array containing an empty string (e.g. new String[]{\"\"}) while building an async logging specification for an MCP server.","commonSituations":"Building client lists dynamically from configuration or environment variables that resolve to an empty array or blank entries; a YAML/properties list that parsed to empty; string-splitting an empty config value producing [\"\"] instead of a zero-length array.","solutions":["Pass at least one non-empty client name in the clients array.","If logging should apply to all clients, check the library API for a wildcard or null/absent-clients overload instead of passing an empty array.","Filter out blank entries before constructing: Arrays.stream(raw).filter(s -> s != null && !s.isBlank()).toArray(String[]::new).","Validate the configuration source (properties/env) actually populated the client list before calling the constructor."],"exampleFix":"// before\nvar spec = new AsyncLoggingSpecification(config.getLoggingClients().split(\",\"), handler);\n// after\nString[] clients = config.getLoggingClients() == null || config.getLoggingClients().isBlank()\n    ? new String[]{\"default-client\"}\n    : Arrays.stream(config.getLoggingClients().split(\",\"))\n        .map(String::trim).filter(s -> !s.isEmpty()).toArray(String[]::new);\nvar spec = new AsyncLoggingSpecification(clients, handler);","handlingStrategy":"validation","validationCode":"String[] clients = /* from config */;\nif (clients == null || clients.length == 0 || Arrays.stream(clients).anyMatch(c -> c == null || c.isEmpty())) {\n    throw new IllegalStateException(\"AsyncLoggingSpecification requires at least one non-empty client name\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    new AsyncLoggingSpecification(clients, handler);\n} catch (IllegalArgumentException e) {\n    logger.error(\"Invalid MCP logging clients config: {}\", e.getMessage());\n}","preventionTips":["Normalize config lists with trim + filter before constructing specifications","Fail startup with a clear message if the client list is empty","Add a unit test covering empty and blank-entry arrays"],"tags":["mcp","validation","constructor","java"],"backgroundTag":"empty-required-field","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}