{"id":"1fb53de1fb32a46a","repo":"spring-projects/spring-framework","slug":"not-enough-arguments-in-method-to-satisfy-binding","errorCode":null,"errorMessage":"Not enough arguments in method to satisfy binding of returning and throwing variables","messagePattern":"Not enough arguments in method to satisfy binding of returning and throwing variables","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java","lineNumber":234,"sourceCode":"\t * for this class for details on the algorithm used.\n\t * @param method the target {@link Method}\n\t * @return the parameter names\n\t */\n\t@Override\n\tpublic @Nullable String @Nullable [] getParameterNames(Method method) {\n\t\tthis.argumentTypes = method.getParameterTypes();\n\t\tthis.numberOfRemainingUnboundArguments = this.argumentTypes.length;\n\t\tthis.parameterNameBindings = new String[this.numberOfRemainingUnboundArguments];\n\n\t\tint minimumNumberUnboundArgs = 0;\n\t\tif (this.returningName != null) {\n\t\t\tminimumNumberUnboundArgs++;\n\t\t}\n\t\tif (this.throwingName != null) {\n\t\t\tminimumNumberUnboundArgs++;\n\t\t}\n\t\tif (this.numberOfRemainingUnboundArguments < minimumNumberUnboundArgs) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Not enough arguments in method to satisfy binding of returning and throwing variables\");\n\t\t}\n\n\t\ttry {\n\t\t\tint algorithmicStep = STEP_JOIN_POINT_BINDING;\n\t\t\twhile (this.numberOfRemainingUnboundArguments > 0 && algorithmicStep < STEP_FINISHED) {\n\t\t\t\tswitch (algorithmicStep++) {\n\t\t\t\t\tcase STEP_JOIN_POINT_BINDING -> {\n\t\t\t\t\t\tif (!maybeBindThisJoinPoint()) {\n\t\t\t\t\t\t\tmaybeBindThisJoinPointStaticPart();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase STEP_THROWING_BINDING -> maybeBindThrowingVariable();\n\t\t\t\t\tcase STEP_ANNOTATION_BINDING -> maybeBindAnnotationsFromPointcutExpression();\n\t\t\t\t\tcase STEP_RETURNING_BINDING -> maybeBindReturningVariable();\n\t\t\t\t\tcase STEP_PRIMITIVE_ARGS_BINDING -> maybeBindPrimitiveArgsFromPointcutExpression();\n\t\t\t\t\tcase STEP_THIS_TARGET_ARGS_BINDING -> maybeBindThisOrTargetOrArgsFromPointcutExpression();\n\t\t\t\t\tcase STEP_REFERENCE_PCUT_BINDING -> maybeBindReferencePointcutParameter();","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java#L216-L252","documentation":"Thrown by AspectJAdviceParameterNameDiscoverer.getParameterNames (line 233-236) when the number of advice method parameters is less than the minimum required to hold both the returning and throwing bindings (one slot each). The discoverer computes minimumNumberUnboundArgs from returningName/throwingName and rejects if the method cannot even accommodate them.","triggerScenarios":"Configuring after-returning/after-throwing binding (or both) on an advice method with too few parameters: e.g. returning='ret' and throwing='ex' both set but the method has only one parameter, or a method with zero parameters and returning set.","commonSituations":"Setting both returning and throwing on a method that has only a join-point parameter; removing a parameter from the advice method but leaving returning/throwing attributes; misconfigured XML combining after-returning and after-throwing semantics on one method.","solutions":["Add enough parameters to the advice method to hold each returning/throwing binding (plus any join-point param).","Remove the returning and/or throwing attribute if the method does not need to bind those values.","Split a single method trying to bind both return and exception into separate after-returning and after-throwing advice methods."],"exampleFix":"// before\n@AfterReturning(value = \"...\", returning = \"ret\", throwing = \"ex\")\npublic void log(JoinPoint jp) { ... } // only 1 param, needs 3\n// after\n@AfterReturning(value = \"...\", returning = \"ret\")\npublic void onRet(JoinPoint jp, Object ret) { ... }\n@AfterThrowing(value = \"...\", throwing = \"ex\")\npublic void onThrow(JoinPoint jp, Throwable ex) { ... }","handlingStrategy":"validation","validationCode":"// Before wiring, verify the advice method can hold returning+throwing bindings.\nint needed = (returningName != null ? 1 : 0) + (throwingName != null ? 1 : 0);\nif (adviceMethod.getParameterCount() < needed) {\n    throw new IllegalStateException(\"Advice \" + adviceMethod + \" has only \"\n        + adviceMethod.getParameterCount() + \" params but \" + needed + \" returning/throwing bindings set\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the advice method declares a parameter for each returning/throwing binding plus any join-point param.","Do not combine returning and throwing on a single advice method; split into after-returning and after-throwing.","Re-count parameters after removing a returning/throwing parameter."],"tags":["spring-aop","aspectj","argument-binding","arity-mismatch","configuration"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}