{"record":{"id":"760c57789b33d83f","repo":"pinpoint-apm/pinpoint","slug":"after-not-allowed-return-arrays-tostring-aft","errorCode":null,"errorMessage":"${after} not allowed return. ${Arrays.toString(afterParamList)}","messagePattern":"(.+?) not allowed return\\. (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java","lineNumber":208,"sourceCode":"            final boolean afterIgnoreMethod = afterMethod.isAnnotationPresent(IgnoreMethod.class);\n\n            if (interceptorType == InterceptorType.RESULT_REPLACE && afterMethod.getReturnType() != Object.class) {\n                // a covariant override would change the weaved call descriptor and break the INVOKEINTERFACE site.\n                throw new RuntimeException(after + \" must return java.lang.Object. \" + targetInterceptorClazz.getName());\n            }\n\n            if (beforeIgnoreMethod && afterIgnoreMethod) {\n                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.NON, null, null);\n            }\n            if (beforeIgnoreMethod) {\n                if (blockType) {\n                    throw new RuntimeException(before + \" not allowed return. \" + Arrays.toString(beforeParamList));\n                }\n                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.AFTER, null, afterMethod);\n            }\n            if (afterIgnoreMethod) {\n                if (blockType) {\n                    throw new RuntimeException(after + \" not allowed return. \" + Arrays.toString(afterParamList));\n                }\n                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.BEFORE, beforeMethod, null);\n            }\n            if (blockType) {\n                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.BLOCK_AROUND, beforeMethod, afterMethod);\n            }\n\n            return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.AROUND, beforeMethod, afterMethod);\n        }\n\n        private Method searchMethod(Class<?> interceptorClazz, String searchMethodName, Class<?>[] searchMethodParameter) {\n            Objects.requireNonNull(searchMethodName, \"searchMethodName\");\n\n//          only DeclaredMethod search ?\n//            try {\n//                return targetInterceptorClazz.getDeclaredMethod(searchMethodName, searchMethodParameter);\n//            } catch (NoSuchMethodException ex) {\n//                logger.debug(searchMethodName + \" DeclaredMethod not found. search parent class\");","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java#L190-L226","documentation":"Symmetric to error 222: the after method is annotated @IgnoreMethod but has a TraceBlock return type (blockType), which is an unsupported combination. The factory throws instead of producing a CaptureType definition with inconsistent semantics.","triggerScenarios":"Building an InterceptorDefinition where the after method carries @IgnoreMethod and the interceptor's before method is TraceBlock-typed (blockType true), taking the afterIgnoreMethod branch.","commonSituations":"Annotating the after method with @IgnoreMethod while keeping block semantics; misconfiguring an around interceptor where only before should block; refactor left @IgnoreMethod on after of a BLOCK_AROUND interceptor.","solutions":["Remove @IgnoreMethod from the after method so BLOCK_AROUND capture is used","Remove the TraceBlock return type from the before method if after-only interception was intended","Split into two interceptor definitions matching the desired capture type"],"exampleFix":"// before\npublic TraceBlock before(...) {...}\n@IgnoreMethod public void after(...) {...}\n// after\npublic TraceBlock before(...) {...}\npublic void after(...) {...}","handlingStrategy":"validation","validationCode":"if (after.isAnnotationPresent(IgnoreMethod.class) && blockType) throw new IllegalStateException(\"IgnoreMethod + TraceBlock after not allowed\");","typeGuard":null,"tryCatchPattern":"try { def = factory.buildInterceptorDefinition(...); } catch (RuntimeException e) { log.error(\"invalid after ignore config: {}\", e.getMessage()); throw e; }","preventionTips":["Do not annotate the after method of a block-type interceptor with @IgnoreMethod","Keep block semantics only on the before method","Test every interceptor definition in CI"],"tags":["java","interceptor","ignore-method","traceblock","invalid-combination"],"backgroundTag":"invalid-argument-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}