{"record":{"id":"cc035866de8e80ed","repo":"spring-projects/spring-framework","slug":"failed-to-bind-all-argument-names-argument-s","errorCode":null,"errorMessage":"Failed to bind all argument names: {} argument(s) could not be bound","messagePattern":"Failed to bind all argument names: (.+?) argument\\(s\\) could not be bound","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java","lineNumber":271,"sourceCode":"\t\t\t\t\tdefault -> throw new IllegalStateException(\"Unknown algorithmic step: \" + (algorithmicStep - 1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (AmbiguousBindingException | IllegalArgumentException ex) {\n\t\t\tif (this.raiseExceptions) {\n\t\t\t\tthrow ex;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tif (this.numberOfRemainingUnboundArguments == 0) {\n\t\t\treturn this.parameterNameBindings;\n\t\t}\n\t\telse {\n\t\t\tif (this.raiseExceptions) {\n\t\t\t\tthrow new IllegalStateException(\"Failed to bind all argument names: \" +\n\t\t\t\t\t\tthis.numberOfRemainingUnboundArguments + \" argument(s) could not be bound\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// convention for failing is to return null, allowing participation in a chain of responsibility\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * An advice method can never be a constructor in Spring.\n\t * @return {@code null}\n\t * @throws UnsupportedOperationException if\n\t * {@link #setRaiseExceptions(boolean) raiseExceptions} has been set to {@code true}\n\t */\n\t@Override\n\tpublic String @Nullable [] getParameterNames(Constructor<?> ctor) {\n\t\tif (this.raiseExceptions) {","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java#L253-L289","documentation":"Thrown by AspectJAdviceParameterNameDiscoverer.getParameterNames (line 270-273) after the full 7-step binding algorithm (join point, throwing, annotation, returning, primitive args, this/target/args, reference pointcut) has run and numberOfRemainingUnboundArguments is still > 0. Every heuristic was exhausted and some parameters could not be assigned a name, so binding cannot complete. Only raised when raiseExceptions is true (which AbstractAspectJAdvice sets at line 461).","triggerScenarios":"An advice method has a parameter that none of the heuristics can name: it is not a JoinPoint/StaticPart, not a Throwable (when throwing set), not an Annotation (when @annotation set), not a primitive (when args() set), and not matchable via this()/target()/args()/reference pointcut. Typically a method with an extra parameter that the pointcut expression does not account for.","commonSituations":"Adding a parameter to an advice method that the pointcut does not bind, compiling without -parameters so names are unavailable, or using a pointcut expression with no bindable forms. Common when migrating from annotation-driven binding to pure pointcut-string binding.","solutions":["Compile with -parameters so DefaultParameterNameDiscoverer can supply names before this discoverer runs.","Add a binding form to the pointcut (args(x), this(x), target(x), @annotation(x)) for each remaining parameter.","Explicitly specify arg-names so the discoverer is bypassed.","Remove parameters the pointcut cannot bind."],"exampleFix":"// before — pointcut binds nothing, advice has an unbindable param, no -parameters\n@After(\"execution(* svc.*(..))\")\npublic void after(JoinPoint jp, Object mystery) { ... }\n\n// after — bind 'mystery' via args() or name it explicitly\n@After(\"execution(* svc.*(..)) && args(mystery)\")\npublic void after(JoinPoint jp, Object mystery) { ... }","handlingStrategy":"validation","validationCode":"import org.springframework.core.DefaultParameterNameDiscoverer;\nimport java.lang.reflect.Method;\n\n// Pre-flight: confirm parameter names are discoverable OR pointcut binds all params.\nboolean bindingWillSucceed(Method adviceMethod, String pointcutExpr) {\n    String[] names = new DefaultParameterNameDiscoverer().getParameterNames(adviceMethod);\n    return names != null; // simplest reliable pre-check; else ensure pointcut binds everything\n}","typeGuard":"boolean namesAvailableOrFullyBound(Method m, String pointcutExpr) {\n    return new org.springframework.core.DefaultParameterNameDiscoverer().getParameterNames(m) != null\n        || pointcutExpr.matches(\".*(args|this|target|@annotation|@args)\\\\(.*\\\\).*\");\n}","tryCatchPattern":"try {\n    advice.getPointcut();\n} catch (IllegalStateException ex) {\n    if (ex.getMessage().contains(\"could not be bound\")) {\n        // add a binding form to the pointcut or compile with -parameters, then retry\n    } else { throw ex; }\n}","preventionTips":["Compile with -parameters so names are always available.","Add a binding form (args/this/target/@annotation) for every non-joinpoint parameter.","Supply arg-names explicitly when in doubt."],"tags":["spring-aop","aspectj","parameter-discovery","argument-binding","compiler"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}