quarkusio/quarkus · error · IllegalStateException

Unable to construct type for ${decorator}: ${e.getMessage()}

Error message

Unable to construct type for ${decorator}: ${e.getMessage()}

What it means

While generating the decorator's proxy class constructor, Arc converts each @Decorates decorated type into a runtime Type via RuntimeTypeCreator. If conversion fails (the IllegalArgumentException case) - typically because a type argument cannot be resolved to a loadable class - the generator aborts with this IllegalStateException.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DecoratorGenerator.java:203

                        for (AnnotationInstance delegateQualifier : decorator.getDelegateQualifiers()) {
                            ClassInfo delegateQualifierClass = decorator.getDeployment()
                                    .getQualifier(delegateQualifier.name());
                            bc.withSet(delegateQualifiers).add(
                                    annotationLiterals.create(bc, delegateQualifierClass, delegateQualifier));
                        }
                        bc.set(cc.this_().field(delegateQualifiersField), delegateQualifiers);

                    }

                    LocalVar tccl = bc.localVar("tccl", bc.invokeVirtual(MethodDescs.THREAD_GET_TCCL, bc.currentThread()));
                    RuntimeTypeCreator rttc = RuntimeTypeCreator.of(bc).withTCCL(tccl);

                    LocalVar decoratedTypes = bc.localVar("decoratedTypes", bc.new_(HashSet.class));
                    for (Type decoratedType : decorator.getDecoratedTypes()) {
                        try {
                            bc.withSet(decoratedTypes).add(rttc.create(decoratedType));
                        } catch (IllegalArgumentException e) {
                            throw new IllegalStateException("Unable to construct type for " + decorator
                                    + ": " + e.getMessage());
                        }
                    }
                    bc.set(cc.this_().field(decoratedTypesField), decoratedTypes);

                    LocalVar delegateType;
                    try {
                        delegateType = rttc.create(decorator.getDelegateType());
                    } catch (IllegalArgumentException e) {
                        throw new IllegalStateException("Unable to construct type for " + decorator
                                + ": " + e.getMessage());
                    }
                    bc.set(cc.this_().field(delegateTypeField), delegateType);
                });
    }

    static boolean isAbstractDecoratorImpl(BeanInfo bean, String providerTypeName) {
        return bean.isDecorator() && ((DecoratorInfo) bean).isAbstract() && providerTypeName.endsWith(ABSTRACT_IMPL_SUFFIX);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure all classes used in the decorated type's generic signature are on the application classpath
  2. Clean rebuild to refresh the bean archive index
  3. Simplify the decorated type's generic parameters (use concrete resolvable types)
  4. Check the decorator's delegate/decorated types for typos in type arguments

Example fix

// before
class MyDecorator implements Converter<SomeMissingClass> { @Decorates ... }
// after
class MyDecorator implements Converter<String> { @Decorates ... }
Defensive patterns

Strategy: validation

Validate before calling

// ensure decorated type raw class is loadable before decorating
static void checkDecoratedType(Class<?> decorated) {
  if (!decorated.isInterface()) throw new IllegalArgumentException("Must be interface: " + decorated);
  for (var t : decorated.getTypeParameters()) System.out.println("type param needs resolvable arg: " + t);
}

Prevention

When it happens

Trigger: A decorator's decorated type (from the interface it implements with @Decorates) uses parameterized types whose raw classes are missing/unloadable in the application index or TCCL during decorator class generation.

Common situations: Decorating a generic interface whose type arguments reference a class that was removed or is in a dependency not on the runtime classpath; split-package/classloading issues in fast-jar.

Related errors


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