{"id":"f02139f6ed8b1ffb","repo":"spring-projects/spring-framework","slug":"returning-argument-name-was-not-bound-in-advi","errorCode":null,"errorMessage":"Returning argument name '{}' was not bound in advice arguments","messagePattern":"Returning argument name '(.+?)' was not bound in advice arguments","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java","lineNumber":488,"sourceCode":"\n\t\tint numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterCount();\n\t\tif (this.argumentNames.length != numExpectedArgumentNames) {\n\t\t\tthrow new IllegalStateException(\"Expecting to find \" + numExpectedArgumentNames +\n\t\t\t\t\t\" arguments to bind by name in advice, but actually found \" +\n\t\t\t\t\tthis.argumentNames.length + \" arguments.\");\n\t\t}\n\n\t\t// So we match in number...\n\t\tint argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind;\n\t\tfor (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {\n\t\t\tthis.argumentBindings.put(this.argumentNames[i], i);\n\t\t}\n\n\t\t// Check that returning and throwing were in the argument names list if\n\t\t// specified, and find the discovered argument types.\n\t\tif (this.returningName != null) {\n\t\t\tif (!this.argumentBindings.containsKey(this.returningName)) {\n\t\t\t\tthrow new IllegalStateException(\"Returning argument name '\" + this.returningName +\n\t\t\t\t\t\t\"' was not bound in advice arguments\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\tInteger index = this.argumentBindings.get(this.returningName);\n\t\t\t\tthis.discoveredReturningType = this.aspectJAdviceMethod.getParameterTypes()[index];\n\t\t\t\tthis.discoveredReturningGenericType = this.aspectJAdviceMethod.getGenericParameterTypes()[index];\n\t\t\t}\n\t\t}\n\t\tif (this.throwingName != null) {\n\t\t\tif (!this.argumentBindings.containsKey(this.throwingName)) {\n\t\t\t\tthrow new IllegalStateException(\"Throwing argument name '\" + this.throwingName +\n\t\t\t\t\t\t\"' was not bound in advice arguments\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\tInteger index = this.argumentBindings.get(this.throwingName);\n\t\t\t\tthis.discoveredThrowingType = this.aspectJAdviceMethod.getParameterTypes()[index];\n\t\t\t}\n\t\t}","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java#L470-L506","documentation":"Thrown by bindExplicitArguments (line 486-490) when returningName is set but does not appear as a key in argumentBindings, i.e. no advice parameter carries that name. After setting a 'returning' binding, Spring requires a matching parameter to receive the return value.","triggerScenarios":"The 'returning' attribute names a value that is not among the advice method's parameter names (and arg-names), or the parameter was omitted from arg-names. E.g. returning=\"ret\" but the advice method's parameter is named 'result' and no arg-names aliasing is provided.","commonSituations":"Renaming the advice parameter without updating the returning attribute; returning attribute referencing a name that doesn't exist; case/typo mismatch between returning and the actual parameter name.","solutions":["Make the 'returning' value exactly match the name of an advice parameter (and include it in arg-names if you supply arg-names).","Add the missing parameter to the advice method so the returning name binds.","Compile with -parameters or specify arg-names consistently so the names line up.","If you do not need to bind the return value, remove the returning attribute."],"exampleFix":"// before\n@AfterReturning(value = \"...\", returning = \"ret\")\npublic void log(Object result) { ... }\n// after\n@AfterReturning(value = \"...\", returning = \"ret\")\npublic void log(Object ret) { ... }","handlingStrategy":"validation","validationCode":"// Ensure the returning name corresponds to an actual parameter name.\nSet<String> paramNames = Set.of(new DefaultParameterNameDiscoverer().getParameterNames(adviceMethod));\nif (returningName != null && !paramNames.contains(returningName)) {\n    throw new IllegalStateException(\n        \"returning='\" + returningName + \"' is not among advice parameters \" + paramNames);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the returning attribute value identical to the bound parameter name.","Rename the returning attribute whenever you rename the parameter.","Compile with -parameters so names are reliably available."],"tags":["spring-aop","aspectj","after-returning","argument-binding","configuration"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}