quarkusio/quarkus · error · IllegalArgumentException

Multiple beans match the type:

Error message

Multiple beans match the type: 

What it means

SchedulerUtils.instantiateBeanOrClass() resolves a task/skip-predicate Class either as a CDI bean (via Arc.container().select) or, if no bean exists, by calling its no-arg constructor. When multiple CDI beans match the requested type with @Any qualifier, the resolution is ambiguous and this IllegalArgumentException is thrown (note: the companion IllegalStateException covers reflection failures).

Source

Thrown at extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java:119

        if (!value.isEmpty() && isConfigValue(value)) {
            value = resolvePropertyExpression(adjustExpressionSyntax(value));
        }
        return value;
    }

    public static boolean isConfigValue(String val) {
        return isSimpleConfigValue(val) || isConfigExpression(val);
    }

    public static ZoneId parseCronTimeZone(Scheduled scheduled) {
        String timeZone = lookUpPropertyValue(scheduled.timeZone());
        return timeZone.equals(Scheduled.DEFAULT_TIMEZONE) ? null : ZoneId.of(timeZone);
    }

    public static <T> T instantiateBeanOrClass(Class<T> type) {
        Instance<T> instance = Arc.container().select(type, Any.Literal.INSTANCE);
        if (instance.isAmbiguous()) {
            throw new IllegalArgumentException("Multiple beans match the type: " + type);
        } else if (instance.isUnsatisfied()) {
            try {
                return type.getConstructor().newInstance();
            } catch (Exception e) {
                throw new IllegalStateException("Unable to instantiate the class: " + type);
            }
        } else {
            return instance.get();
        }
    }

    private static boolean isSimpleConfigValue(String val) {
        val = val.trim();
        return val.startsWith("{") && val.endsWith("}");
    }

    /**
     * Converts "{property}" to "${property}" for backwards compatibility

View on GitHub (pinned to e1c734241f)

Solutions

  1. Disambiguate the container: mark one bean @Alternative with @Priority, or use @Named and select by qualifier
  2. Remove or deactivate the duplicate bean (e.g. mock only active in the test profile without also keeping the production bean)
  3. Make the duplicate non-bean (@Vetoed or remove @ApplicationScoped) so instantiation falls back to the constructor
  4. Change the scheduled configuration to reference a unique concrete class

Example fix

// before
class MyTask {...} and @Mock class MyTaskMock extends MyTask {...} // both beans
// after
@Mock @Alternative @Priority(1)
class MyTaskMock extends MyTask {...} // ambiguity resolved
Defensive patterns

Strategy: validation

Validate before calling

Instance<T> check = Arc.container().select(type, Any.Literal.INSTANCE);
if (check.isAmbiguous()) {
    throw new IllegalStateException("Multiple beans of " + type + " - add @Alternative/@Priority or @Vetoed");
}

Type guard

boolean uniquelyResolvable(Class<?> type) {
    Instance<?> i = Arc.container().select(type, Any.Literal.INSTANCE);
    return !i.isAmbiguous();
}

Try / catch

try {
    task = SchedulerUtils.instantiateBeanOrClass(MyTask.class);
} catch (IllegalArgumentException e) {
    LOG.error("Ambiguous CDI beans for {} - qualify or veto duplicates", type, e);
}

Prevention

When it happens

Trigger: Passing a Class to setTask/setAsyncTask/setSkipPredicate (or calling instantiateBeanOrClass directly) where two or more beans of that type exist in the CDI container, e.g. a bean plus a @Mock bean in tests, or multiple implementations/specializations of the same interface type.

Common situations: Test profiles adding a @Mock/@Alternative duplicate of a scheduled task bean; two beans of the same class in different packages both eligible; forgetting @Alternative/@Priority on a test replacement; accidentally making an abstract task class a bean.

Related errors


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