{"id":"c87802cf4fbf4333","repo":"spring-projects/spring-framework","slug":"advice-method-requires-arguments-to-be-bou","errorCode":null,"errorMessage":"Advice method [{}] requires {} arguments to be bound by name, but the argument names were not specified and could not be discovered.","messagePattern":"Advice method \\[(.+?)\\] requires (.+?) arguments to be bound by name, but the argument names were not specified and could not be discovered\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java","lineNumber":441,"sourceCode":"\t\tif (JoinPoint.StaticPart.class == candidateParameterType) {\n\t\t\tthis.joinPointStaticPartArgumentIndex = 0;\n\t\t\treturn true;\n\t\t}\n\t\telse {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate void bindArgumentsByName(int numArgumentsExpectingToBind) {\n\t\tif (this.argumentNames == null) {\n\t\t\tthis.argumentNames = createParameterNameDiscoverer().getParameterNames(this.aspectJAdviceMethod);\n\t\t}\n\t\tif (this.argumentNames != null) {\n\t\t\t// We have been able to determine the arg names.\n\t\t\tbindExplicitArguments(numArgumentsExpectingToBind);\n\t\t}\n\t\telse {\n\t\t\tthrow new IllegalStateException(\"Advice method [\" + this.aspectJAdviceMethod.getName() + \"] \" +\n\t\t\t\t\t\"requires \" + numArgumentsExpectingToBind + \" arguments to be bound by name, but \" +\n\t\t\t\t\t\"the argument names were not specified and could not be discovered.\");\n\t\t}\n\t}\n\n\t/**\n\t * Create a ParameterNameDiscoverer to be used for argument binding.\n\t * <p>The default implementation creates a {@link DefaultParameterNameDiscoverer}\n\t * and adds a specifically configured {@link AspectJAdviceParameterNameDiscoverer}.\n\t */\n\tprotected ParameterNameDiscoverer createParameterNameDiscoverer() {\n\t\t// We need to discover them, or if that fails, guess,\n\t\t// and if we can't guess with 100% accuracy, fail.\n\t\tDefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();\n\t\tAspectJAdviceParameterNameDiscoverer adviceParameterNameDiscoverer =\n\t\t\t\tnew AspectJAdviceParameterNameDiscoverer(this.pointcut.getExpression());\n\t\tadviceParameterNameDiscoverer.setReturningName(this.returningName);\n\t\tadviceParameterNameDiscoverer.setThrowingName(this.throwingName);","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java#L423-L459","documentation":"Thrown by bindArgumentsByName (line 432-445) when the advice method has parameters requiring name-based binding but argumentNames is null and the ParameterNameDiscoverer chain (including AspectJAdviceParameterNameDiscoverer) could not discover them. Spring cannot map pointcut bindings to advice parameters without names.","triggerScenarios":"An advice method with one or more parameters that must be bound from the pointcut (e.g. args(x)) where: arg-names is not provided, the class was compiled without -parameters (so reflection can't read names), and the AspectJAdviceParameterNameDiscoverer could not deduce them unambiguously from the pointcut expression.","commonSituations":"Building/running without the -parameters javac flag; obfuscated/stripped bytecode; complex pointcuts the heuristic discoverer cannot resolve (multiple unbound args, no this/target/args binding form); advice methods whose param names were never compiled in.","solutions":["Compile with -parameters (javac / Maven compiler-plugin / Gradle '--parameters') so reflection can read parameter names.","Add an explicit 'arg-names' attribute (XML) or 'argNames' in the annotation listing each advice parameter name.","Simplify the pointcut so the binding is unambiguous (single unbound arg, clear args()/this()/target() binding form).","Annotate parameter names via a discoverer that supplies them, or refactor the advice to take a JoinPoint plus fewer bound params."],"exampleFix":"// before\n@AfterReturning(value = \"args(req)\", returning = \"ret\")\npublic void log(Object req, Object ret) { ... } // compiled without -parameters\n// after (option A)\n@AfterReturning(value = \"args(req)\", returning = \"ret\", argNames = \"req,ret\")\npublic void log(Object req, Object ret) { ... }\n// after (option B) compile with -parameters","handlingStrategy":"validation","validationCode":"// Before relying on discovery, confirm parameter names are obtainable.\nParameterNameDiscoverer d = new DefaultParameterNameDiscoverer();\nString[] names = d.getParameterNames(adviceMethod);\nif (names == null && adviceMethod.getParameterCount() > 0) {\n    throw new IllegalStateException(\n        \"Parameter names unavailable for \" + adviceMethod + \" — compile with -parameters or supply arg-names\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Compile all modules containing aspects with -parameters (javac/maven/gradle).","Supply explicit arg-names for advice with bound parameters when -parameters is unavailable.","Keep pointcuts simple enough for unambiguous discovery as a fallback.","Add a build check that fails if aspect classes lack parameter names."],"tags":["spring-aop","aspectj","argument-binding","parameters-flag","configuration"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}