quarkusio/quarkus · error · DefinitionException

interceptor method validation message (dynamically built: mu

Error message

interceptor method validation message (dynamically built: must have exactly one parameter of type jakarta.interceptor.InvocationContext / zero parameters / correct return type, per interception type and placement)

What it means

ArC's validateSignature throws this DefinitionException when an interceptor method (annotated @AroundInvoke, @AroundConstruct, @PostConstruct or @PreDestroy) has an invalid signature for its interception type and placement. Depending on the type, the method must have exactly one parameter of type jakarta.interceptor.InvocationContext (around methods), zero parameters (lifecycle callbacks), and a permitted return type (Object, or void for lifecycle callbacks in target classes).

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java:394

                if (errors.contains(InterceptorMethodError.MUST_HAVE_PARAMETER)
                        || errors.contains(InterceptorMethodError.MUST_NOT_HAVE_PARAMETER)) {
                    msg.append(" and must ");
                }
                msg.append("have a return type of ");
                if (mayReturnVoid) {
                    msg.append("void");
                }
                if (mayReturnVoid && mayReturnObject) {
                    msg.append(" or ");
                }
                if (mayReturnObject) {
                    msg.append("java.lang.Object");
                }
            }

            msg.append(": ").append(method).append(" declared in ").append(method.declaringClass().name());

            throw new DefinitionException(msg.toString());
        }
    }

}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the @AroundInvoke/@AroundConstruct method signature to take exactly one jakarta.interceptor.InvocationContext parameter and return Object (or the required type).
  2. Change @PostConstruct/@PreDestroy callback methods to take zero parameters (and a permitted void return).
  3. Verify you are importing jakarta.interceptor.InvocationContext, not the legacy javax one.

Example fix

// before
@AroundInvoke void intercept(String name) { }
// after
@AroundInvoke Object intercept(InvocationContext ctx) throws Exception { return ctx.proceed(); }
Defensive patterns

Strategy: validation

Validate before calling

// Verify interceptor method signature before use
static boolean isValidAroundInvoke(java.lang.reflect.Method m) {
    if (!m.isAnnotationPresent(jakarta.interceptor.AroundInvoke.class)) return true;
    return m.getParameterCount() == 1
        && m.getParameterTypes()[0] == jakarta.interceptor.InvocationContext.class
        && m.getReturnType() != void.class;
}

Type guard

static boolean hasInvocationContextSignature(java.lang.reflect.Method m) {
    return m.getParameterCount() == 1
        && jakarta.interceptor.InvocationContext.class.isAssignableFrom(m.getParameterTypes()[0]);
}

Prevention

When it happens

Trigger: @AroundInvoke/@AroundConstruct method with zero or multiple parameters, or a first parameter not of type InvocationContext; @PostConstruct/@PreDestroy method with any parameter; wrong return type for the interception type (e.g. @AroundInvoke returning void where Object is required).

Common situations: Hand-writing interceptor methods from memory with wrong signatures; using javax.interceptor.InvocationContext instead of jakarta.interceptor.InvocationContext after a Jakarta EE migration; typos like a generic parameter type; copying a target-class interceptor method into an interceptor class (or vice versa) where rules differ.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/fb127de9f935881b. Report an issue: GitHub.