{"record":{"id":"b7609777fe70b842","repo":"quarkusio/quarkus","slug":"invalid-argument-combination-requiredtype-be","errorCode":null,"errorMessage":"Invalid argument combination ${requiredType}; ${beanType}","messagePattern":"Invalid argument combination (.+?); (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/BeanTypeAssignabilityRules.java","lineNumber":96,"sourceCode":"     *\n     */\n    private boolean matches(Class<?> type1, ParameterizedType type2) {\n        if (!type1.equals(Types.getRawType(type2))) {\n            return false;\n        }\n        return Types.isArrayOfUnboundedTypeVariablesOrObjects(type2.getActualTypeArguments());\n    }\n\n    /**\n     * A parameterized bean type is considered assignable to a parameterized required type if they have identical raw type and\n     * for each parameter:\n     */\n    private boolean matches(ParameterizedType requiredType, ParameterizedType beanType) {\n        if (!requiredType.getRawType().equals(beanType.getRawType())) {\n            return false;\n        }\n        if (requiredType.getActualTypeArguments().length != beanType.getActualTypeArguments().length) {\n            throw new IllegalArgumentException(\"Invalid argument combination \" + requiredType + \"; \" + beanType);\n        }\n        for (int i = 0; i < requiredType.getActualTypeArguments().length; i++) {\n            if (!parametersMatch(requiredType.getActualTypeArguments()[i], beanType.getActualTypeArguments()[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /*\n     * Actual type parameters\n     */\n\n    protected boolean parametersMatch(Type requiredParameter, Type beanParameter) {\n        if (Types.isActualType(requiredParameter) && Types.isActualType(beanParameter)) {\n            /*\n             * the required type parameter and the bean type parameter are actual types with identical raw type, and, if the\n             * type is parameterized, the bean","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/BeanTypeAssignabilityRules.java#L78-L114","documentation":"BeanTypeAssignabilityRules.matches() compares a required parameterized type with a bean's parameterized type. If the raw types are equal but the number of actual type arguments differs (e.g. comparing `List<String>` with a raw `List` or a differently-erased generic), ArC throws IllegalArgumentException because assignability cannot be evaluated for mismatched arity. This normally indicates corrupted or improperly resolved type information.","triggerScenarios":"Resolving/injecting beans whose required Type is a ParameterizedType whose actual-type-argument count differs from the bean's resolved ParameterizedType (e.g. raw types mixed with generics, or hand-built ParameterizedType instances).","commonSituations":"Custom extension/portable-extension code constructing Type instances manually; reflection-obtained types where a raw class was used instead of its generic form; classloader/version mismatches giving inconsistent generic signatures.","solutions":["Ensure the required type you pass to BeanManager.getBeans()/injection resolution carries the same number of type arguments as the bean type (avoid raw types).","In portable extensions, build required types with Types utilities (e.g. Types.getParameterizedType) instead of assembling ParameterizedType by hand.","Check for mixed ArC/library versions that could resolve generics inconsistently; do a clean rebuild."],"exampleFix":"// before\nType required = ArrayList.class; // raw type, 0 args vs bean's ArrayList<String>\n\n// after\nType required = Types.getParameterizedType(ArrayList.class, String.class); // match arity","handlingStrategy":"validation","validationCode":"static boolean arityMatches(ParameterizedType a, ParameterizedType b) {\n    return a.getRawType().equals(b.getRawType())\n        && a.getActualTypeArguments().length == b.getActualTypeArguments().length;\n}","typeGuard":"static boolean isFullyParameterized(Type t) {\n    return !(t instanceof ParameterizedType)\n        || ((ParameterizedType) t).getActualTypeArguments().length > 0;\n}","tryCatchPattern":"try {\n    resolveBean(requiredType);\n} catch (IllegalArgumentException e) {\n    if (!e.getMessage().startsWith(\"Invalid argument combination\")) throw e;\n    // log malformed type and skip\n}","preventionTips":["Never pass raw types where the bean type is generic; always construct parameterized types with matching arity.","Use ArC's Types utility methods to build required types in extensions.","Keep Quarkus/ArC versions aligned across modules to avoid inconsistent generic resolution."],"tags":["cdi","generics","type-assignability","quarkus-arc"],"backgroundTag":"generic-type-mismatch","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}