{"record":{"id":"1e929e7797f0e265","repo":"spring-projects/spring-framework","slug":"found-candidate-this-target-or-args-var","errorCode":null,"errorMessage":"Found {} candidate this(), target(), or args() variables but only one unbound argument slot","messagePattern":"Found (.+?) candidate this\\(\\), target\\(\\), or args\\(\\) variables but only one unbound argument slot","errorType":"exception","errorClass":"AmbiguousBindingException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java","lineNumber":517,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t\telse if (tokens[i].equals(\"args\") || tokens[i].startsWith(\"args(\")) {\n\t\t\t\tPointcutBody body = getPointcutBody(tokens, i);\n\t\t\t\ti += body.numTokensConsumed;\n\t\t\t\tList<String> candidateVarNames = new ArrayList<>();\n\t\t\t\tmaybeExtractVariableNamesFromArgs(body.text, candidateVarNames);\n\t\t\t\t// we may have found some var names that were bound in previous primitive args binding step,\n\t\t\t\t// filter them out...\n\t\t\t\tfor (String varName : candidateVarNames) {\n\t\t\t\t\tif (!alreadyBound(varName)) {\n\t\t\t\t\t\tvarNames.add(varName);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (varNames.size() > 1) {\n\t\t\tthrow new AmbiguousBindingException(\"Found \" + varNames.size() +\n\t\t\t\t\t\" candidate this(), target(), or args() variables but only one unbound argument slot\");\n\t\t}\n\t\telse if (varNames.size() == 1) {\n\t\t\tfor (int j = 0; j < this.parameterNameBindings.length; j++) {\n\t\t\t\tif (isUnbound(j)) {\n\t\t\t\t\tbindParameterName(j, varNames.get(0));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// else varNames.size must be 0 and we have nothing to bind.\n\t}\n\n\tprivate void maybeBindReferencePointcutParameter() {\n\t\tif (this.numberOfRemainingUnboundArguments > 1) {\n\t\t\tthrow new AmbiguousBindingException(\"Still \" + this.numberOfRemainingUnboundArguments +\n\t\t\t\t\t\" unbound args at reference pointcut binding stage, with no way to determine between them\");\n\t\t}","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java#L499-L535","documentation":"Thrown when exactly one unbound argument slot remains but the pointcut's this()/target()/args() expressions yield multiple candidate variable names. Spring cannot pick which candidate to bind to the single remaining slot.","triggerScenarios":"A pointcut like target(t) && args(a) with an advice method that has exactly one unbound parameter — e.g. void before(Object t). The algorithm finds two candidate variable names (t and a) but only one slot. Only fires when setRaiseExceptions(true).","commonSituations":"Multiple binding designators in a pointcut but the advice takes fewer parameters, compiled without -parameters.","solutions":["Compile with -parameters to resolve parameter names directly","Reduce the pointcut to a single binding designator matching the single remaining parameter","Add the missing parameter to the advice method so each candidate variable has its own slot"],"exampleFix":"// before\n@Before(\"target(t) && args(a)\")\npublic void before(Object t) { ... } // 2 candidates, 1 slot\n\n// after\n@Before(\"target(t)\")\npublic void before(Object t) { ... }","handlingStrategy":"validation","validationCode":"// If only one param slot is unbound, ensure the pointcut has at most one of this()/target()/args() binding\nlong bindingDesignators = Arrays.stream(new String[]{\"this(\",\"target(\",\"args(\"})\n    .filter(pointcutExpr::contains).count();\nint unbound = /* computed as in error 23 */ 1;\nif (unbound == 1 && bindingDesignators > 1) {\n    throw new IllegalStateException(\"Multiple this()/target()/args() bindings but only one unbound slot\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    discoverer.getParameterNames(adviceMethod);\n} catch (AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException ex) {\n    // Reduce binding designators to one, or add params for each\n}","preventionTips":["Compile with -parameters","Match the number of this()/target()/args() binding variables to the number of unbound advice parameters"],"tags":["spring-aop","aspectj","this-target-args","parameter-binding"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}