{"record":{"id":"61ad90b7cffb4aaa","repo":"pinpoint-apm/pinpoint","slug":"either-interceptor-or-interceptorfactory-must-be-p","errorCode":null,"errorMessage":"either interceptor or interceptorFactory must be present.","messagePattern":"either interceptor or interceptorFactory must be present\\.","errorType":"exception","errorClass":"InstrumentException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMInterceptorHolder.java","lineNumber":244,"sourceCode":"            final int interceptorId = interceptorHolderIdGenerator.getId();\n            final ASMInterceptorHolder holder = new ASMInterceptorHolder(interceptorId);\n            final Class<?> clazz;\n            if (classLoader == null || isReflectionDelegatingClassLoader(classLoader)) {\n                // define into the bootstrap classloader, eagerly create the interceptor\n                clazz = holder.defineClass(null);\n                if (interceptor == null && interceptorFactory != null) {\n                    interceptor = interceptorFactory.newInterceptor(interceptorClass, providedArguments, scopeInfo, methodDescriptor);\n                }\n            } else {\n                clazz = holder.defineClass(classLoader);\n            }\n            // exception handling.\n            if (interceptor != null) {\n                holder.init(clazz, interceptor);\n            } else if (interceptorFactory != null) {\n                holder.init(clazz, interceptorFactory, interceptorClass, providedArguments, scopeInfo, methodDescriptor);\n            } else {\n                throw new InstrumentException(\"either interceptor or interceptorFactory must be present.\");\n            }\n\n            return holder;\n        }\n    }\n\n    static class RenameClassAdapter extends ClassVisitor {\n        private final String newInternalName;\n\n        public RenameClassAdapter(ClassVisitor classVisitor, String name) {\n            super(ASMVersion.VERSION, classVisitor);\n            this.newInternalName = JavaAssistUtils.javaNameToJvmName(name);\n        }\n\n        @Override\n        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {\n            super.visit(version, access, this.newInternalName, signature, superName, interfaces);\n        }","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMInterceptorHolder.java#L226-L262","documentation":"InstrumentException thrown by ASMInterceptorHolder.Builder.build when neither an interceptor class nor an interceptor factory was supplied before building the interceptor holder. The builder requires one of the two to know how to initialize the holder, so it fails fast instead of producing a broken interceptor.","triggerScenarios":"Calling build() on a builder where neither setInterceptor(Class) nor setInterceptorFactory(...) was invoked; a plugin passing null/omitting the interceptor registration call in its instrumentation code.","commonSituations":"Plugin authors forgetting to call setInterceptor after setInterceptables; conditional code paths that skip interceptor setup; refactoring a plugin and accidentally dropping the interceptor setter call.","solutions":["Call builder.setInterceptor(MyInterceptor.class) (or the factory variant) before build()","If the interceptor is conditional, ensure both branches configure either the interceptor or a factory","Add an assertion/log before build() to confirm interceptor configuration is present"],"exampleFix":"// before\nreturn newBuilder().interceptMethod(method).build();\n// after\nreturn newBuilder().interceptMethod(method).interceptor(MyInterceptor.class).build();","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(interceptorClass, \"interceptorClass\"); // or interceptorFactory\nbuilder.interceptor(interceptorClass).build();","typeGuard":"boolean readyForBuild(Builder b) { return b.hasInterceptor() || b.hasInterceptorFactory(); }","tryCatchPattern":"try {\n    return builder.build();\n} catch (InstrumentException e) {\n    if (e.getMessage().contains(\"interceptor or interceptorFactory\")) {\n        logger.error(\"plugin interceptor not configured\", e);\n    }\n    throw e;\n}","preventionTips":["Always set interceptor or factory immediately after creating the builder","Unit-test plugin transform methods with a builder that mimics the real flow","Never conditionally skip interceptor setup without also setting a factory"],"tags":["instrumentation","missing-argument","builder"],"backgroundTag":"missing-required-argument","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}