{"record":{"id":"b4ad0f5c9d8c0c27","repo":"spring-projects/spring-ai","slug":"updated-prompts-list-must-not-be-null","errorCode":null,"errorMessage":"Updated prompts list must not be null","messagePattern":"Updated prompts list must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/prompt/SyncMcpPromptListChangedMethodCallback.java","lineNumber":56,"sourceCode":"\t\timplements Consumer<List<McpSchema.Prompt>> {\n\n\tprivate SyncMcpPromptListChangedMethodCallback(Builder builder) {\n\t\tsuper(builder.method, builder.bean);\n\t}\n\n\t/**\n\t * Accept the prompt list change notification and process it.\n\t * <p>\n\t * This method builds the arguments for the method call and invokes the method.\n\t * @param updatedPrompts The updated list of prompts, must not be null\n\t * @throws McpPromptListChangedConsumerMethodException if there is an error invoking\n\t * the prompt list changed consumer method\n\t * @throws IllegalArgumentException if the updatedPrompts is null\n\t */\n\t@Override\n\tpublic void accept(List<McpSchema.Prompt> updatedPrompts) {\n\t\tif (updatedPrompts == null) {\n\t\t\tthrow new IllegalArgumentException(\"Updated prompts list must not be null\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Build arguments for the method call\n\t\t\tObject[] args = this.buildArgs(this.method, null, updatedPrompts);\n\n\t\t\t// Invoke the method\n\t\t\tthis.method.setAccessible(true);\n\t\t\tthis.method.invoke(this.bean, args);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new McpPromptListChangedConsumerMethodException(\n\t\t\t\t\t\"Error invoking prompt list changed consumer method: \" + this.method.getName(), e);\n\t\t}\n\t}\n\n\t/**\n\t * Validates that the method return type is compatible with the prompt list changed","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/prompt/SyncMcpPromptListChangedMethodCallback.java#L38-L74","documentation":"IllegalArgumentException thrown by SyncMcpPromptListChangedMethodCallback.accept(List<McpSchema.Prompt>) when the incoming updatedPrompts list is null. The callback forwards the prompt list to the user's consumer method; a null list cannot be mapped to a valid method argument, so it is rejected before reflective invocation.","triggerScenarios":"The MCP server/framework invoking accept(null) — typically when a prompts/list_changed notification carries no parseable prompt list or a caller passes null directly to the callback. Not caused by user handler code itself.","commonSituations":"Custom or wrapped MCP client plumbing passing null notifications; tests calling accept(null) directly; version mismatches where the notification payload shape changed and deserialization yielded null.","solutions":["Fix the caller so it passes an empty list (List.of()) instead of null when no prompts exist.","If you invoke the callback manually (e.g. in tests), pass List.of() rather than null.","If this comes from deserialization of the notification, check client/server version compatibility of the MCP schema."],"exampleFix":"// before\ncallback.accept(null);\n// after\ncallback.accept(List.of());","handlingStrategy":"validation","validationCode":"if (updatedPrompts == null) {\n    updatedPrompts = List.of();\n}\ncallback.accept(updatedPrompts);","typeGuard":"static List<McpSchema.Prompt> nullSafe(List<McpSchema.Prompt> prompts) {\n    return prompts != null ? prompts : List.of();\n}","tryCatchPattern":"try {\n    callback.accept(updatedPrompts);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Updated prompts list must not be null\")) {\n        log.warn(\"Null prompt list notification — substituting empty list\");\n        callback.accept(List.of());\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always pass List.of() instead of null when there are no prompts.","Fix upstream deserialization so notifications never yield null lists.","In tests, exercise accept with both empty and populated lists."],"tags":["mcp","null-argument","callback","reflective-invocation"],"backgroundTag":"null-argument","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"}