{"record":{"id":"eb65cc578251a91f","repo":"quarkusio/quarkus","slug":"invalid-scheduler-implementations-detected","errorCode":null,"errorMessage":"Invalid scheduler implementations detected: ","messagePattern":"Invalid scheduler implementations detected: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java","lineNumber":126,"sourceCode":"\n    static final String INVOKER_SUFFIX = \"_ScheduledInvoker\";\n    static final String NESTED_SEPARATOR = \"$_\";\n\n    @BuildStep\n    SchedulerImplementationBuildItem implementation() {\n        return new SchedulerImplementationBuildItem(Scheduled.SIMPLE, DotName.createSimple(SimpleScheduler.class), 0);\n    }\n\n    @BuildStep\n    void compositeScheduler(SchedulerConfig config, List<SchedulerImplementationBuildItem> implementations,\n            BuildProducer<AdditionalBeanBuildItem> additionalBeans,\n            BuildProducer<DiscoveredImplementationsBuildItem> discoveredImplementations) {\n        List<SchedulerImplementationBuildItem> sorted = implementations.stream()\n                .sorted(Comparator.comparingInt(SchedulerImplementationBuildItem::getPriority).reversed()).toList();\n        Set<String> found = sorted.stream().map(SchedulerImplementationBuildItem::getImplementation)\n                .collect(Collectors.toUnmodifiableSet());\n        if (found.size() != implementations.size()) {\n            throw new IllegalStateException(\"Invalid scheduler implementations detected: \" + implementations);\n        }\n        DiscoveredImplementationsBuildItem discovered = new DiscoveredImplementationsBuildItem(\n                sorted.get(0).getImplementation(), found,\n                config.useCompositeScheduler());\n        discoveredImplementations.produce(discovered);\n        if (implementations.size() > 1 && config.useCompositeScheduler()) {\n            // If multiple implementations are needed we have to register the CompositeScheduler, and\n            // instruct the extensions that provide an implementation to modify the bean metadata, i.e. add the marker qualifier\n            additionalBeans.produce(AdditionalBeanBuildItem.builder()\n                    .addBeanClasses(Constituent.class, CompositeScheduler.class).setUnremovable().build());\n        }\n    }\n\n    @BuildStep\n    void transformSchedulerBeans(DiscoveredImplementationsBuildItem discoveredImplementations,\n            List<SchedulerImplementationBuildItem> implementations,\n            BuildProducer<AnnotationsTransformerBuildItem> transformer) {\n        if (discoveredImplementations.isCompositeSchedulerUsed()) {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java#L108-L144","documentation":"When multiple scheduler implementations are discovered (each registered via a SchedulerImplementationBuildItem with a priority), the processor verifies that each implementation name is unique. Duplicate implementation identifiers make the composite/sorted selection ambiguous, so build fails listing the offending build items.","triggerScenarios":"Two extensions (or the same extension registered twice) produce SchedulerImplementationBuildItems with the same implementation name string.","commonSituations":"Having both quarkus-quartz and a custom scheduler extension exposing the same implementation id; accidentally producing the build item twice in a custom @BuildStep; stale duplicate jars on the classpath.","solutions":["Remove one of the duplicate scheduler extensions/dependencies from the application","Ensure your custom @BuildStep produces the SchedulerImplementationBuildItem only once","Use a unique implementation name for custom scheduler implementations","Check for duplicate/stale jars carrying the same scheduler implementation"],"exampleFix":"// before\n@BuildStep\nvoid implA(BuildProducer<SchedulerImplementationBuildItem> p) {\n  p.produce(new SchedulerImplementationBuildItem(\"quartz\", 5, ...));\n}\n@BuildStep\nvoid implB(BuildProducer<SchedulerImplementationBuildItem> p) {\n  p.produce(new SchedulerImplementationBuildItem(\"quartz\", 5, ...)); // duplicate\n}\n// after: produce it once, or use a distinct name e.g. \"my-scheduler\"","handlingStrategy":"validation","validationCode":"Set<String> names = new HashSet<>();\nfor (SchedulerImplementationBuildItem i : implementations) {\n    if (!names.add(i.getImplementation()))\n        throw new IllegalStateException(\"Duplicate scheduler implementation: \" + i.getImplementation());\n}","typeGuard":null,"tryCatchPattern":"try { /* build */ } catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Invalid scheduler implementations\")) { /* dedupe build steps */ }\n}","preventionTips":["Use a unique implementation id per scheduler extension","Produce SchedulerImplementationBuildItem exactly once","Check dependency tree for duplicate scheduler extensions","Name custom implementations distinctively"],"tags":["scheduler","build-time","extension-conflict","quarkus"],"backgroundTag":"duplicate-extension-implementation","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"}