quarkusio/quarkus · error · IllegalArgumentException

phase + " methods can't declare a parameter of type " + (typ

Error message

phase + " methods can't declare a parameter of type " + (typeName != null ? typeName.withoutPackagePrefix() : this.name()) + ", found at " + method

What it means

Arc's build-time extension processor validates that each parameter of a CDI-lite extension method (@Init/@Registration/@Enhancement/@Synthesis etc.) is allowed in the phase the method belongs to. ExtensionMethodParameter.verifyAvailable() throws IllegalArgumentException when the declared parameter type is not in the validPhases set for the given ExtensionPhase, telling you the method and the offending type name.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionMethodParameter.java:57

    private final Set<ExtensionPhase> validPhases;

    ExtensionMethodParameter(DotName typeName, boolean isQuery, ExtensionPhase... validPhases) {
        this.typeName = typeName;
        this.isQuery = isQuery;
        if (validPhases == null || validPhases.length == 0) {
            this.validPhases = EnumSet.noneOf(ExtensionPhase.class);
        } else {
            this.validPhases = EnumSet.copyOf(Arrays.asList(validPhases));
        }
    }

    boolean isQuery() {
        return isQuery;
    }

    void verifyAvailable(ExtensionPhase phase, ExtensionMethod method) {
        if (!validPhases.contains(phase)) {
            throw new IllegalArgumentException(phase + " methods can't declare a parameter of type "
                    + (typeName != null ? typeName.withoutPackagePrefix() : this.name())
                    + ", found at " + method);
        }
    }

    static ExtensionMethodParameter of(org.jboss.jandex.Type type) {
        if (type.kind() == org.jboss.jandex.Type.Kind.CLASS) {
            for (ExtensionMethodParameter candidate : ExtensionMethodParameter.values()) {
                if (candidate.typeName.equals(type.name())) {
                    return candidate;
                }
            }
        }

        return UNKNOWN;
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Move the method to the extension phase whose validPhases includes the parameter type (e.g. move BeanInfo params to @Registration methods).
  2. Replace the offending parameter with one valid for the current phase (e.g. ClassConfig/MethodConfig/FieldConfig for @Enhancement, ClassInfo/MethodInfo/FieldInfo query types as appropriate).
  3. Remove the invalid parameter and obtain the needed metadata through the method's query parameter or invocation metadata instead.
  4. Rebuild so the Arc processor re-runs and confirms no other methods mix phase-invalid parameters.

Example fix

// before
@Enhancement
void enhance(ClassConfig config, BeanInfo bean) { ... }

// after (BeanInfo is registration-phase only)
@Enhancement
void enhance(ClassConfig config) { ... }
Defensive patterns

Strategy: validation

Validate before calling

Set<String> allowed = Set.of("ClassConfig","MethodConfig","FieldConfig"); // per phase
if (!allowed.contains(paramType.getSimpleName())) {
    throw new IllegalStateException(paramType + " not valid for " + phase + " method " + methodName);
}

Type guard

static boolean isValidForPhase(org.jboss.jandex.Type t, ExtensionPhase phase) {
    return switch (phase) {
        case ENHANCEMENT -> isQueryInfoOrConfig(t);
        case REGISTRATION -> isBeanInfoOrObserverInfo(t);
        default -> false;
    };
}

Try / catch

try {
    extensionProcessor.process(methods);
} catch (IllegalArgumentException e) {
    throw new BuildFailure("Invalid extension method parameter: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Declaring a build-time extension method in a class processed by Arc's bcextensions support whose signature mixes parameter types across phases, e.g. an @Enhancement method taking a BeanInfo, or a @Registration method taking a ClassConfig, so verifyAvailable(phase, method) finds the type missing from validPhases.

Common situations: Migrating a classic CDI portable extension to the new build-time extension model and copy-pasting method signatures between phases; misremembering which phase consumes Config vs Info types; autocompleting a parameter type that belongs to another lifecycle phase.

Related errors


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