{"record":{"id":"a395387547b59c74","repo":"spring-projects/spring-ai","slug":"failed-to-assign-all-uri-variables-to-method-param","errorCode":null,"errorMessage":"Failed to assign all URI variables to method parameters. Assigned: ${assigned}, Expected: ${expected}","messagePattern":"Failed to assign all URI variables to method parameters\\. Assigned: (.+?), Expected: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java","lineNumber":503,"sourceCode":"\t\t\t// handled)\n\t\t\t// or if it's already assigned (exchange or request)\n\t\t\tif (parameters[i].isAnnotationPresent(McpProgressToken.class)\n\t\t\t\t\t|| McpMeta.class.isAssignableFrom(parameters[i].getType()) || args[i] != null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Assign the next URI variable\n\t\t\tif (variableIndex < this.uriVariables.size()) {\n\t\t\t\tString variableName = this.uriVariables.get(variableIndex);\n\t\t\t\targs[i] = uriVariableValues.get(variableName);\n\t\t\t\tassignedVariables.add(variableName);\n\t\t\t\tvariableIndex++;\n\t\t\t}\n\t\t}\n\n\t\t// Verify all URI variables were assigned\n\t\tif (assignedVariables.size() != this.uriVariables.size()) {\n\t\t\tthrow new IllegalArgumentException(\"Failed to assign all URI variables to method parameters. \"\n\t\t\t\t\t+ \"Assigned: \" + assignedVariables + \", Expected: \" + this.uriVariables);\n\t\t}\n\t}\n\n\t/**\n\t * Builds arguments for methods without URI variables. This method provides common\n\t * argument building logic for methods without URI variables.\n\t * @param parameters The method parameters\n\t * @param args The arguments array to populate\n\t * @param exchange The server exchange\n\t * @param request The resource request\n\t */\n\tprotected void buildArgsWithoutUriVariables(Parameter[] parameters, Object[] args, Object exchange,\n\t\t\tReadResourceRequest request) {\n\t\tfor (int i = 0; i < parameters.length; i++) {\n\t\t\t// Skip if parameter is annotated with @McpProgressToken or is McpMeta\n\t\t\t// (already handled)\n\t\t\tif (parameters[i].isAnnotationPresent(McpProgressToken.class)","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java#L485-L521","documentation":"Thrown at invocation time by buildArgsWithUriVariables when URI variable values from the incoming request could not all be matched/assigned to method parameters. The number of assigned variables differs from the template's declared URI variables.","triggerScenarios":"A client requests a URI whose extracted variable values don't map onto the method's String parameters (e.g. template has {a}/{b} but the resolved request only yields one value, or a value is null/missing), so assignedVariables.size() != this.uriVariables.size().","commonSituations":"Client calling a resource URI that doesn't fully match the template (missing path segment); template variables with unsupported patterns; mismatch between the uriVariables list used at registration and the runtime URI.","solutions":["Check the client's requested URI fully matches the resource template including every variable segment","Log and inspect uriVariableValues to see which variable is missing","Re-register the resource with a corrected @McpResource uri template consistent with the method signature"],"exampleFix":"// client request causing failure: docs/read (template docs/{page})\n// fix client call to include the variable:\n// before: resources/read?uri=docs/read\n// after:  resources/read?uri=docs/intro","handlingStrategy":"try-catch","validationCode":"McpUriTemplateManager tm = new DefaultMcpUriTemplateManagerFactory().create(templateUri);\nif (!tm.matches(requestedUri)) throw new IllegalArgumentException(\"URI \" + requestedUri + \" does not match template \" + templateUri);","typeGuard":null,"tryCatchPattern":"try {\n    Object result = callback.call(exchange, request);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Failed to assign all URI variables\")) {\n        return errorResponse(INVALID_PARAMS, \"Resource URI must match template: \" + e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Validate client-requested URIs against the template before dispatch","Log the extracted uriVariableValues map to spot missing segments","Ensure the registration-time uriVariables list matches the runtime URI parsing"],"tags":["mcp","java","uri-template","runtime","argument-binding"],"backgroundTag":"missing-required-argument","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"}