{"record":{"id":"b48bc408e06adb18","repo":"spring-projects/spring-ai","slug":"clients-must-not-be-empty-b48bc4","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/changed/tool/SyncToolListChangedSpecification.java","lineNumber":31,"sourceCode":" * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.springframework.ai.mcp.annotation.method.changed.tool;\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 SyncToolListChangedSpecification(String[] clients, Consumer<List<McpSchema.Tool>> toolListChangeHandler) {\n\n\tpublic SyncToolListChangedSpecification {\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(toolListChangeHandler, \"toolListChangeHandler must not be null\");\n\t}\n\n}\n","sourceCodeStart":13,"sourceCodeEnd":37,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/tool/SyncToolListChangedSpecification.java#L13-L37","documentation":"The compact constructor of the SyncToolListChangedSpecification record validates its inputs: clients must be non-null, non-empty after trimming, and contain no blank entries; toolListChangeHandler must be non-null. A clients array that is null/empty or contains only whitespace triggers this IllegalArgumentException.","triggerScenarios":"Creating SyncToolListChangedSpecification with new String[0], with a clients array containing empty or whitespace-only strings, or calling annotation-processor registration where the @McpToolListChanged clients attribute resolves to nothing.","commonSituations":"Omitting the clients attribute on the annotation so it defaults to an empty array; building client names dynamically and producing blank strings; typo leaving the array unfilled.","solutions":["Pass at least one non-blank client name, e.g. new SyncToolListChangedSpecification(new String[]{\"myClient\"}, handler).","Trim/verify client names programmatically before constructing the specification.","Fix the @McpToolListChanged(clients = ...) attribute to list the actual MCP client/connection names."],"exampleFix":"// before\nnew SyncToolListChangedSpecification(new String[]{\"\"}, handler); // throws\n// after\nnew SyncToolListChangedSpecification(new String[]{\"client1\"}, handler);","handlingStrategy":"validation","validationCode":"String[] clients = ...; // from config/annotation\nif (clients == null || Arrays.stream(clients).map(String::trim).allMatch(String::isEmpty)) {\n    throw new IllegalStateException(\"at least one non-blank client name required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    var spec = new SyncToolListChangedSpecification(clients, handler);\n} catch (IllegalArgumentException e) {\n    LOG.error(\"invalid clients for tool-list-changed spec: {}\", e.getMessage());\n}","preventionTips":["Explicitly set the clients attribute on @McpToolListChanged.","Validate client name lists for blank entries at config load time.","Fail fast at application startup if the client list is empty."],"tags":["mcp","validation","empty-argument","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-14T11:17:12.474Z"}