{"record":{"id":"2252268bdcbf5bde","repo":"gradle/gradle","slug":"the-interceptor-s-callerclassname-parameter-shoul","errorCode":null,"errorMessage":"The interceptor's @CallerClassName parameter should be last or just before @InjectVisitorContext if that parameter is present","messagePattern":"The interceptor's @CallerClassName parameter should be last or just before @InjectVisitorContext if that parameter is present","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":550,"sourceCode":"        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            }\n        }\n\n        if (callable.hasKotlinDefaultMaskParam()) {\n            // TODO support @AfterConstructor with Kotlin default mask? Kotlin constructors have a special DefaultConstructorMarker as the last argument\n            if (callable.getKind() != CallableKindInfo.STATIC_METHOD && callable.getKind() != CallableKindInfo.INSTANCE_METHOD) {\n                throw new Failure(\n                    \"Only @\" + CallableKind.StaticMethod.class.getSimpleName() + \" or @\" + CallableKind.InstanceMethod.class.getSimpleName() + \" can use Kotlin default parameters\"\n                );\n            }\n\n            int expectedKotlinDefaultMaskIndex = callable.getParameters().size() - (hasCallerClassName ? 2 : 1);\n            if (callable.getParameters().get(expectedKotlinDefaultMaskIndex).getKind() != ParameterKindInfo.KOTLIN_DEFAULT_MASK) {\n                throw new Failure(\n                    \"@\" + ParameterKind.KotlinDefaultMask.class.getSimpleName() + \" should be the last parameter of may be followed only by @\" + ParameterKind.CallerClassName.class.getSimpleName()","sourceCodeStart":532,"sourceCodeEnd":568,"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#L532-L568","documentation":"Error \"The interceptor's @CallerClassName parameter should be last or just before @InjectVisitorContext if that parameter is present\" thrown in gradle/gradle.","triggerScenarios":"An @CallerClassName parameter is placed somewhere other than last (or just before @InjectVisitorContext).","commonSituations":"Ordering mistakes when declaring interceptor parameters.","solutions":["Move the @CallerClassName parameter to the last position, or just before the @InjectVisitorContext parameter if one is present."],"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"}