gradle/gradle · error · Failure

The interceptor's @InjectVisitorContext parameter should be

Error message

The interceptor's @InjectVisitorContext parameter should be last parameter

What it means

Error "The interceptor's @InjectVisitorContext parameter should be last parameter" thrown in gradle/gradle.

Source

Thrown at platforms/core-runtime/internal-instrumentation-processor/src/main/java/org/gradle/internal/instrumentation/processor/codegen/jvmbytecode/InterceptJvmCallsGenerator.java:536

        String implementationDescriptor = request.getImplementationInfo().getDescriptor();

        method.addStatement("$N._POP()", METHOD_VISITOR_PARAM); // pops the default method signature marker
        maybeGenerateLoadBinaryClassNameCall(method, interceptedCallable);
        maybeGenerateGetStaticInjectVisitorContext(method, interceptedCallable);
        method.addStatement("$N._INVOKESTATIC($N, $S, $S)", METHOD_VISITOR_PARAM, ownerTypeField, implementationName, implementationDescriptor);
        method.addStatement("return true");
    }

    private static void validateSignature(CallableInfo callable) {
        if (callable.getKind() == CallableKindInfo.GROOVY_PROPERTY_GETTER || callable.getKind() == CallableKindInfo.GROOVY_PROPERTY_SETTER) {
            throw new Failure("Groovy property access cannot be intercepted in JVM calls");
        }

        boolean hasInjectVisitorContext = callable.hasInjectVisitorContextParam();
        if (hasInjectVisitorContext) {
            ParameterInfo lastParameter = callable.getParameters().get(callable.getParameters().size() - 1);
            if (lastParameter.getKind() != ParameterKindInfo.INJECT_VISITOR_CONTEXT) {
                throw new Failure("The interceptor's @" + ParameterKind.InjectVisitorContext.class.getSimpleName() + " parameter should be last parameter");
            }
            if (!lastParameter.getParameterType().getClassName().equals(BytecodeInterceptorFilter.class.getName())) {
                throw new Failure("The interceptor's @" + ParameterKind.InjectVisitorContext.class.getSimpleName() + " parameter should be of type " + BytecodeInterceptorFilter.class.getName() + " but was " + lastParameter.getParameterType().getClassName());
            }
            if (callable.getParameters().stream().filter(it -> it.getKind() == ParameterKindInfo.INJECT_VISITOR_CONTEXT).count() > 1) {
                throw new Failure("An interceptor may not have more than one @" + ParameterKind.InjectVisitorContext.class.getSimpleName() + " parameter");
            }
        }

        boolean hasCallerClassName = callable.hasCallerClassNameParam();
        if (hasCallerClassName) {
            int expectedIndex = hasInjectVisitorContext ? callable.getParameters().size() - 2 : callable.getParameters().size() - 1;
            if (callable.getParameters().get(expectedIndex).getKind() != ParameterKindInfo.CALLER_CLASS_NAME) {
                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");
            }
            if (callable.getParameters().stream().filter(it -> it.getKind() == ParameterKindInfo.CALLER_CLASS_NAME).count() > 1) {
                throw new Failure("An interceptor may not have more than one @" + ParameterKind.CallerClassName.class.getSimpleName() + " parameter");
            }

View on GitHub (pinned to 534f27719b)

Solutions

  1. Move the @InjectVisitorContext parameter to the last position of the interceptor method signature.

When it happens

Trigger: An interceptor method has an @InjectVisitorContext parameter that is not the last parameter.

Common situations: Declaring interceptor signatures with parameters after the visitor-context parameter.


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/eb75e88ffbad216c. Report an issue: GitHub.