{"id":"65fbc6af771a55ce","repo":"spring-projects/spring-framework","slug":"found-unbound-primitive-arguments-with-no-way-t","errorCode":null,"errorMessage":"Found {} unbound primitive arguments with no way to distinguish between them.","messagePattern":"Found (.+?) unbound primitive arguments with no way to distinguish between them\\.","errorType":"exception","errorClass":"AmbiguousBindingException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java","lineNumber":644,"sourceCode":"\t\t\t\tsb.append(toAppend);\n\t\t\t\tsb.append(' ');\n\t\t\t\tcurrentIndex++;\n\t\t\t\tnumTokensConsumed++;\n\t\t\t}\n\n\t\t}\n\n\t\t// We looked and failed...\n\t\treturn new PointcutBody(numTokensConsumed, null);\n\t}\n\n\t/**\n\t * Match up args against unbound arguments of primitive types.\n\t */\n\tprivate void maybeBindPrimitiveArgsFromPointcutExpression() {\n\t\tint numUnboundPrimitives = countNumberOfUnboundPrimitiveArguments();\n\t\tif (numUnboundPrimitives > 1) {\n\t\t\tthrow new AmbiguousBindingException(\"Found \" + numUnboundPrimitives +\n\t\t\t\t\t\" unbound primitive arguments with no way to distinguish between them.\");\n\t\t}\n\t\tif (numUnboundPrimitives == 1) {\n\t\t\t// Look for arg variable and bind it if we find exactly one...\n\t\t\tList<String> varNames = new ArrayList<>();\n\t\t\tString[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, \" \");\n\t\t\tfor (int i = 0; i < tokens.length; i++) {\n\t\t\t\tif (tokens[i].equals(\"args\") || tokens[i].startsWith(\"args(\")) {\n\t\t\t\t\tPointcutBody body = getPointcutBody(tokens, i);\n\t\t\t\t\ti += body.numTokensConsumed;\n\t\t\t\t\tmaybeExtractVariableNamesFromArgs(body.text, varNames);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (varNames.size() > 1) {\n\t\t\t\tthrow new AmbiguousBindingException(\"Found \" + varNames.size() +\n\t\t\t\t\t\t\" candidate variable names but only one candidate binding slot when matching primitive args\");\n\t\t\t}\n\t\t\telse if (varNames.size() == 1) {","sourceCodeStart":626,"sourceCodeEnd":662,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java#L626-L662","documentation":"Thrown when more than one unbound primitive-typed argument remains at the primitive-args binding stage. Since multiple primitive args cannot be told apart without compiled names, Spring refuses to guess. Only surfaces when raiseExceptions=true.","triggerScenarios":"An advice method with two or more primitive parameters (int, long, boolean, etc.) that are not bound by earlier stages, reached the primitive args() binding step.","commonSituations":"Advice methods monitoring methods with multiple primitive arguments bound via args() without -parameters; refactor adding a second primitive parameter.","solutions":["Compile with -parameters so primitive parameter names are available.","Reduce to a single unbound primitive parameter by binding others via explicit args() position or removing them.","Wrap primitives or use a single composite parameter."],"exampleFix":"// before\n@Before(\"execution(* com.acme.*.*(int,int)) && args(a,b)\")\npublic void before(int a, int b) { ... }\n\n// after\n// compile with -parameters, OR bind a single primitive and pass the rest explicitly:\n@Before(\"execution(* com.acme.*.*(int,int)) && args(a,*)\")\npublic void before(int a) { ... }","handlingStrategy":"validation","validationCode":"// Ensure at most one unbound primitive param:\nlong unboundPrimitives = Arrays.stream(method.getParameterTypes())\n    .filter(Class::isPrimitive).count();\nassert unboundPrimitives <= 1;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Compile with -parameters.","Bind all but one primitive explicitly via args().","Avoid advice methods binding multiple primitives without compiled names."],"tags":["spring-aop","aspectj","advice-binding","primitive"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}