{"record":{"id":"4553dddaf91f8a1a","repo":"spring-projects/spring-ai","slug":"only-one-of-prompt-or-uri-can-be-provided-in-mcpco","errorCode":null,"errorMessage":"Only one of prompt or uri can be provided in McpComplete annotation","messagePattern":"Only one of prompt or uri can be provided in McpComplete annotation","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/adapter/CompleteAdapter.java","lineNumber":55,"sourceCode":"\t/**\n\t * Convert a McpComplete annotation to a McpSchema.CompleteReference object.\n\t * @param mcpComplete The McpComplete annotation\n\t * @return The corresponding McpSchema.CompleteReference object\n\t * @throws IllegalArgumentException if neither prompt nor uri is provided, or if both\n\t * are provided\n\t */\n\tpublic static McpSchema.CompleteReference asCompleteReference(McpComplete mcpComplete) {\n\t\tAssert.notNull(mcpComplete, \"mcpComplete cannot be null\");\n\n\t\tString prompt = mcpComplete.prompt();\n\t\tString uri = mcpComplete.uri();\n\n\t\t// Validate that either prompt or uri is provided, but not both\n\t\tif ((prompt == null || prompt.isEmpty()) && (uri == null || uri.isEmpty())) {\n\t\t\tthrow new IllegalArgumentException(\"Either prompt or uri must be provided in McpComplete annotation\");\n\t\t}\n\t\tif ((prompt != null && !prompt.isEmpty()) && (uri != null && !uri.isEmpty())) {\n\t\t\tthrow new IllegalArgumentException(\"Only one of prompt or uri can be provided in McpComplete annotation\");\n\t\t}\n\n\t\t// Create the appropriate reference type based on what's provided\n\t\tif (prompt != null && !prompt.isEmpty()) {\n\t\t\treturn McpSchema.PromptReference.builder(prompt).build();\n\t\t}\n\t\telse {\n\t\t\treturn new McpSchema.ResourceReference(uri);\n\t\t}\n\t}\n\n\t/**\n\t * Convert a McpComplete annotation and Method to a McpSchema.CompleteReference\n\t * object.\n\t * @param mcpComplete The McpComplete annotation\n\t * @param method The method annotated with McpComplete\n\t * @return The corresponding McpSchema.CompleteReference object\n\t * @throws IllegalArgumentException if neither prompt nor uri is provided, or if both","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/adapter/CompleteAdapter.java#L37-L73","documentation":"CompleteAdapter.asCompleteReference enforces the MCP rule that a completion reference names exactly one target: a prompt OR a resource URI, never both. This error is thrown when the McpComplete annotation has both a non-empty prompt and a non-empty uri.","triggerScenarios":"Calling asCompleteReference on an @McpComplete annotation where both prompt() and uri() return non-empty values, e.g. @McpComplete(prompt = \"x\", uri = \"file:///y\").","commonSituations":"Copy-pasting an annotation example that had uri and adding prompt for a different use; IDE auto-completing both attributes; merging code from two branches each setting a different attribute.","solutions":["Remove the uri attribute if the completion targets a prompt","Remove the prompt attribute if the completion targets a resource URI","Split into two separate @McpComplete annotations, one per target"],"exampleFix":"// before\n@McpComplete(prompt = \"code-review\", uri = \"file:///logs/{path}\")\npublic List<String> complete(String argument) { ... }\n\n// after\n@McpComplete(prompt = \"code-review\")\npublic List<String> complete(String argument) { ... }","handlingStrategy":"validation","validationCode":"boolean promptSet = ann.prompt() != null && !ann.prompt().isEmpty();\nboolean uriSet = ann.uri() != null && !ann.uri().isEmpty();\nif (promptSet && uriSet) {\n    throw new IllegalStateException(\"@McpComplete allows only one of prompt or uri\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never set both prompt and uri on the same @McpComplete","Keep annotation attributes populated from a single template field","Review annotations in code review for mutually exclusive attributes"],"tags":["mcp","annotation-validation","completion"],"backgroundTag":"mutually-exclusive-options","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"}