{"record":{"id":"76ce4fa200137511","repo":"quarkusio/quarkus","slug":"phase-methods-can-t-declare-a-parameter-of-typ","errorCode":null,"errorMessage":"phase + \" methods can't declare a parameter of type \" + (typeName != null ? typeName.withoutPackagePrefix() : this.name()) + \", found at \" + method","messagePattern":"phase \\+ \" methods can't declare a parameter of type \" \\+ \\(typeName != null \\? typeName\\.withoutPackagePrefix\\(\\) : this\\.name\\(\\)\\) \\+ \", found at \" \\+ method","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionMethodParameter.java","lineNumber":57,"sourceCode":"    private final Set<ExtensionPhase> validPhases;\n\n    ExtensionMethodParameter(DotName typeName, boolean isQuery, ExtensionPhase... validPhases) {\n        this.typeName = typeName;\n        this.isQuery = isQuery;\n        if (validPhases == null || validPhases.length == 0) {\n            this.validPhases = EnumSet.noneOf(ExtensionPhase.class);\n        } else {\n            this.validPhases = EnumSet.copyOf(Arrays.asList(validPhases));\n        }\n    }\n\n    boolean isQuery() {\n        return isQuery;\n    }\n\n    void verifyAvailable(ExtensionPhase phase, ExtensionMethod method) {\n        if (!validPhases.contains(phase)) {\n            throw new IllegalArgumentException(phase + \" methods can't declare a parameter of type \"\n                    + (typeName != null ? typeName.withoutPackagePrefix() : this.name())\n                    + \", found at \" + method);\n        }\n    }\n\n    static ExtensionMethodParameter of(org.jboss.jandex.Type type) {\n        if (type.kind() == org.jboss.jandex.Type.Kind.CLASS) {\n            for (ExtensionMethodParameter candidate : ExtensionMethodParameter.values()) {\n                if (candidate.typeName.equals(type.name())) {\n                    return candidate;\n                }\n            }\n        }\n\n        return UNKNOWN;\n    }\n}\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/bcextensions/ExtensionMethodParameter.java#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Move the method to the extension phase whose validPhases includes the parameter type (e.g. move BeanInfo params to @Registration methods).","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).","Remove the invalid parameter and obtain the needed metadata through the method's query parameter or invocation metadata instead.","Rebuild so the Arc processor re-runs and confirms no other methods mix phase-invalid parameters."],"exampleFix":"// before\n@Enhancement\nvoid enhance(ClassConfig config, BeanInfo bean) { ... }\n\n// after (BeanInfo is registration-phase only)\n@Enhancement\nvoid enhance(ClassConfig config) { ... }","handlingStrategy":"validation","validationCode":"Set<String> allowed = Set.of(\"ClassConfig\",\"MethodConfig\",\"FieldConfig\"); // per phase\nif (!allowed.contains(paramType.getSimpleName())) {\n    throw new IllegalStateException(paramType + \" not valid for \" + phase + \" method \" + methodName);\n}","typeGuard":"static boolean isValidForPhase(org.jboss.jandex.Type t, ExtensionPhase phase) {\n    return switch (phase) {\n        case ENHANCEMENT -> isQueryInfoOrConfig(t);\n        case REGISTRATION -> isBeanInfoOrObserverInfo(t);\n        default -> false;\n    };\n}","tryCatchPattern":"try {\n    extensionProcessor.process(methods);\n} catch (IllegalArgumentException e) {\n    throw new BuildFailure(\"Invalid extension method parameter: \" + e.getMessage(), e);\n}","preventionTips":["Keep a table of which parameter types belong to which extension phase and consult it when writing methods.","One method = one phase concern; never mix Info and Config parameters from different phases.","Let the Arc processor fail fast in dev builds before packaging."],"tags":["arc","cdi","build-time-extension","quarkus"],"backgroundTag":"invalid-extension-method-parameter","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}