{"record":{"id":"eb75e88ffbad216c","repo":"gradle/gradle","slug":"the-interceptor-s-injectvisitorcontext-parameter","errorCode":null,"errorMessage":"The interceptor's @InjectVisitorContext parameter should be last parameter","messagePattern":"The interceptor's @InjectVisitorContext parameter should be last parameter","errorType":"exception","errorClass":"Failure","httpStatus":null,"severity":"error","filePath":"platforms/core-runtime/internal-instrumentation-processor/src/main/java/org/gradle/internal/instrumentation/processor/codegen/jvmbytecode/InterceptJvmCallsGenerator.java","lineNumber":536,"sourceCode":"        String implementationDescriptor = request.getImplementationInfo().getDescriptor();\n\n        method.addStatement(\"$N._POP()\", METHOD_VISITOR_PARAM); // pops the default method signature marker\n        maybeGenerateLoadBinaryClassNameCall(method, interceptedCallable);\n        maybeGenerateGetStaticInjectVisitorContext(method, interceptedCallable);\n        method.addStatement(\"$N._INVOKESTATIC($N, $S, $S)\", METHOD_VISITOR_PARAM, ownerTypeField, implementationName, implementationDescriptor);\n        method.addStatement(\"return true\");\n    }\n\n    private static void validateSignature(CallableInfo callable) {\n        if (callable.getKind() == CallableKindInfo.GROOVY_PROPERTY_GETTER || callable.getKind() == CallableKindInfo.GROOVY_PROPERTY_SETTER) {\n            throw new Failure(\"Groovy property access cannot be intercepted in JVM calls\");\n        }\n\n        boolean hasInjectVisitorContext = callable.hasInjectVisitorContextParam();\n        if (hasInjectVisitorContext) {\n            ParameterInfo lastParameter = callable.getParameters().get(callable.getParameters().size() - 1);\n            if (lastParameter.getKind() != ParameterKindInfo.INJECT_VISITOR_CONTEXT) {\n                throw new Failure(\"The interceptor's @\" + ParameterKind.InjectVisitorContext.class.getSimpleName() + \" parameter should be last parameter\");\n            }\n            if (!lastParameter.getParameterType().getClassName().equals(BytecodeInterceptorFilter.class.getName())) {\n                throw new Failure(\"The interceptor's @\" + ParameterKind.InjectVisitorContext.class.getSimpleName() + \" parameter should be of type \" + BytecodeInterceptorFilter.class.getName() + \" but was \" + lastParameter.getParameterType().getClassName());\n            }\n            if (callable.getParameters().stream().filter(it -> it.getKind() == ParameterKindInfo.INJECT_VISITOR_CONTEXT).count() > 1) {\n                throw new Failure(\"An interceptor may not have more than one @\" + ParameterKind.InjectVisitorContext.class.getSimpleName() + \" parameter\");\n            }\n        }\n\n        boolean hasCallerClassName = callable.hasCallerClassNameParam();\n        if (hasCallerClassName) {\n            int expectedIndex = hasInjectVisitorContext ? callable.getParameters().size() - 2 : callable.getParameters().size() - 1;\n            if (callable.getParameters().get(expectedIndex).getKind() != ParameterKindInfo.CALLER_CLASS_NAME) {\n                throw new Failure(\"The interceptor's @\" + ParameterKind.CallerClassName.class.getSimpleName() + \" parameter should be last or just before @\" + ParameterKind.InjectVisitorContext.class.getSimpleName() + \" if that parameter is present\");\n            }\n            if (callable.getParameters().stream().filter(it -> it.getKind() == ParameterKindInfo.CALLER_CLASS_NAME).count() > 1) {\n                throw new Failure(\"An interceptor may not have more than one @\" + ParameterKind.CallerClassName.class.getSimpleName() + \" parameter\");\n            }","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/core-runtime/internal-instrumentation-processor/src/main/java/org/gradle/internal/instrumentation/processor/codegen/jvmbytecode/InterceptJvmCallsGenerator.java#L518-L554","documentation":"Error \"The interceptor's @InjectVisitorContext parameter should be last parameter\" thrown in gradle/gradle.","triggerScenarios":"An interceptor method has an @InjectVisitorContext parameter that is not the last parameter.","commonSituations":"Declaring interceptor signatures with parameters after the visitor-context parameter.","solutions":["Move the @InjectVisitorContext parameter to the last position of the interceptor method signature."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}