{"record":{"id":"74b11859a511688e","repo":"spring-projects/spring-ai","slug":"clients-must-not-be-empty-74b118","errorCode":null,"errorMessage":"clients must not be empty","messagePattern":"clients must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/resource/SyncResourceListChangedSpecification.java","lineNumber":32,"sourceCode":" * limitations under the License.\n */\n\npackage org.springframework.ai.mcp.annotation.method.changed.resource;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.function.Consumer;\n\nimport io.modelcontextprotocol.spec.McpSchema;\n\npublic record SyncResourceListChangedSpecification(String[] clients,\n\t\tConsumer<List<McpSchema.Resource>> resourceListChangeHandler) {\n\n\tpublic SyncResourceListChangedSpecification {\n\t\tObjects.requireNonNull(clients, \"clients must not be null\");\n\t\tif (clients.length == 0 || Arrays.stream(clients).map(String::trim).anyMatch(String::isEmpty)) {\n\t\t\tthrow new IllegalArgumentException(\"clients must not be empty\");\n\t\t}\n\t\tObjects.requireNonNull(resourceListChangeHandler, \"resourceListChangeHandler 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/changed/resource/SyncResourceListChangedSpecification.java#L14-L38","documentation":"The compact constructor of SyncResourceListChangedSpecification validates that the `clients` array is non-null and contains no null/blank entries. The library requires at least one named MCP client so the resource-list-changed specification can be registered against a concrete client connection; an empty array would silently produce a no-op subscription.","triggerScenarios":"Calling the annotation-processing registration path with new SyncResourceListChangedSpecification(new String[0], handler), or passing an array whose entries are all null/whitespace strings (e.g. new String[]{\"\"} or new String[]{\" \"}) — both hit `clients.length == 0` or the anyMatch(String::isEmpty) check and throw IllegalArgumentException.","commonSituations":"Spring configuration mistakes where client names are read from properties (e.g. a property like @mcp.clients that is empty or unset), splitting an empty string producing [\"\"], or refactoring code so the clients array is no longer populated before building the specification.","solutions":["Pass at least one valid MCP client name in the clients array, e.g. new SyncResourceListChangedSpecification(new String[]{\"client1\"}, handler)","Check the source of the client names (properties/env/config bean) and verify it is populated and non-empty before constructing the specification","Trim and filter the candidate names before passing them, and fail fast with a clear message if the filtered list is empty"],"exampleFix":"// before\nSyncResourceListChangedSpecification spec = new SyncResourceListChangedSpecification(\n    config.getClients().split(\",\"), handler); // throws when config value is empty\n// after\nString[] clients = java.util.Arrays.stream(config.getClients().split(\",\"))\n    .map(String::trim).filter(s -> !s.isEmpty()).toArray(String[]::new);\nif (clients.length == 0) throw new IllegalStateException(\"No MCP clients configured\");\nSyncResourceListChangedSpecification spec = new SyncResourceListChangedSpecification(clients, handler);","handlingStrategy":"validation","validationCode":"if (clients == null || clients.length == 0 || java.util.Arrays.stream(clients).map(String::trim).anyMatch(String::isEmpty)) { throw new IllegalArgumentException(\"clients must contain at least one non-blank name\"); }","typeGuard":"static boolean validClients(String[] clients) { return clients != null && clients.length > 0 && java.util.Arrays.stream(clients).noneMatch(c -> c == null || c.trim().isEmpty()); }","tryCatchPattern":"try { new SyncResourceListChangedSpecification(clients, handler); } catch (IllegalArgumentException e) { log.error(\"Bad clients argument: {}\", e.getMessage()); }","preventionTips":["Filter and trim client names before constructing the specification","Fail at configuration-load time if the clients property is empty","Unit-test registration helpers with empty and blank inputs"],"tags":["java","validation","mcp","empty-array"],"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-14T05:17:10.506Z"}