pinpoint-apm/pinpoint · error · RuntimeException

${after} not allowed return. ${Arrays.toString(afterParamLis

Error message

${after} not allowed return. ${Arrays.toString(afterParamList)}

What it means

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.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java:208

            final boolean afterIgnoreMethod = afterMethod.isAnnotationPresent(IgnoreMethod.class);

            if (interceptorType == InterceptorType.RESULT_REPLACE && afterMethod.getReturnType() != Object.class) {
                // a covariant override would change the weaved call descriptor and break the INVOKEINTERFACE site.
                throw new RuntimeException(after + " must return java.lang.Object. " + targetInterceptorClazz.getName());
            }

            if (beforeIgnoreMethod && afterIgnoreMethod) {
                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.NON, null, null);
            }
            if (beforeIgnoreMethod) {
                if (blockType) {
                    throw new RuntimeException(before + " not allowed return. " + Arrays.toString(beforeParamList));
                }
                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.AFTER, null, afterMethod);
            }
            if (afterIgnoreMethod) {
                if (blockType) {
                    throw new RuntimeException(after + " not allowed return. " + Arrays.toString(afterParamList));
                }
                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.BEFORE, beforeMethod, null);
            }
            if (blockType) {
                return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.BLOCK_AROUND, beforeMethod, afterMethod);
            }

            return new DefaultInterceptorDefinition(interceptorClazz, targetInterceptorClazz, interceptorType, CaptureType.AROUND, beforeMethod, afterMethod);
        }

        private Method searchMethod(Class<?> interceptorClazz, String searchMethodName, Class<?>[] searchMethodParameter) {
            Objects.requireNonNull(searchMethodName, "searchMethodName");

//          only DeclaredMethod search ?
//            try {
//                return targetInterceptorClazz.getDeclaredMethod(searchMethodName, searchMethodParameter);
//            } catch (NoSuchMethodException ex) {
//                logger.debug(searchMethodName + " DeclaredMethod not found. search parent class");

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Remove @IgnoreMethod from the after method so BLOCK_AROUND capture is used
  2. Remove the TraceBlock return type from the before method if after-only interception was intended
  3. Split into two interceptor definitions matching the desired capture type

Example fix

// before
public TraceBlock before(...) {...}
@IgnoreMethod public void after(...) {...}
// after
public TraceBlock before(...) {...}
public void after(...) {...}
Defensive patterns

Strategy: validation

Validate before calling

if (after.isAnnotationPresent(IgnoreMethod.class) && blockType) throw new IllegalStateException("IgnoreMethod + TraceBlock after not allowed");

Try / catch

try { def = factory.buildInterceptorDefinition(...); } catch (RuntimeException e) { log.error("invalid after ignore config: {}", e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Building an InterceptorDefinition where the after method carries @IgnoreMethod and the interceptor's before method is TraceBlock-typed (blockType true), taking the afterIgnoreMethod branch.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/760c57789b33d83f. Report an issue: GitHub.