{"record":{"id":"c07b6e92a16e78ac","repo":"quarkusio/quarkus","slug":"a-skip-predicate-instance-cannot-be-scheduled-prog","errorCode":null,"errorMessage":"A skip predicate instance cannot be scheduled programmatically if DB store type is used; register a skip predicate class instead","messagePattern":"A skip predicate instance cannot be scheduled programmatically if DB store type is used; register a skip predicate class instead","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java","lineNumber":878,"sourceCode":"        @Override\n        public Class<? extends Consumer<ScheduledExecution>> taskClass() {\n            return taskClass;\n        }\n\n        @Override\n        public Class<? extends Function<ScheduledExecution, Uni<Void>>> asyncTaskClass() {\n            return asyncTaskClass;\n        }\n\n        @Override\n        public Class<? extends SkipPredicate> skipPredicateClass() {\n            return skipPredicateClass;\n        }\n\n        @Override\n        public QuartzJobDefinition setSkipPredicate(SkipPredicate skipPredicate) {\n            if (storeType.isDbStore() && skipPredicateClass == null) {\n                throw new IllegalStateException(\n                        \"A skip predicate instance cannot be scheduled programmatically if DB store type is used; register a skip predicate class instead\");\n            }\n            return super.setSkipPredicate(skipPredicate);\n        }\n\n        @Override\n        public QuartzJobDefinition setTask(Consumer<ScheduledExecution> task, boolean runOnVirtualThread) {\n            if (storeType.isDbStore() && taskClass == null) {\n                throw new IllegalStateException(\n                        \"A task instance cannot be scheduled programmatically if DB store type is used; register a task class instead\");\n            }\n            return super.setTask(task, runOnVirtualThread);\n        }\n\n        @Override\n        public QuartzJobDefinition setAsyncTask(Function<ScheduledExecution, Uni<Void>> asyncTask) {\n            if (storeType.isDbStore() && asyncTaskClass == null) {\n                throw new IllegalStateException(","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java#L860-L896","documentation":"With `quarkus.quartz.store-type=db`, job definitions are persisted to the database and must be reconstructible by class name. A lambda/instance SkipPredicate cannot be serialized, so `setSkipPredicate(SkipPredicate)` rejects instances and demands a registered SkipPredicate class.","triggerScenarios":"Calling `quartzJobDefinition.setSkipPredicate(someLambdaOrInstance)` while the scheduler's store type is DB and `setSkipPredicateClass` was not called first.","commonSituations":"Local tests with in-memory store work but the app fails in prod with DB store; using a lambda `s -> shouldSkip(s)` for skip logic.","solutions":["Implement SkipPredicate in a named CDI bean/class and register it via `setSkipPredicateClass(MySkipPredicate.class)` before scheduling","Switch store type to memory if persistence is not needed (`quarkus.quartz.store-type=memory`)","Instantiate the predicate with a no-arg constructor-capable class and pass the class, not an instance"],"exampleFix":"// before\njob.setSkipPredicate(ctx -> isHoliday(ctx.getScheduledFireTime()));\n// after\njob.setSkipPredicateClass(HolidaySkipPredicate.class); // implements SkipPredicate","handlingStrategy":"validation","validationCode":"if (quarkusQuartzConfig.storeType().isDbStore()) {\n    job.setSkipPredicateClass(MySkipPredicate.class);\n} else {\n    job.setSkipPredicate(ctx -> check(ctx));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Gate programmatic job building on store type","Prefer class-based predicates everywhere for consistency across environments","Document store-type assumptions next to job definitions"],"tags":["quarkus","quartz","db-store","serialization"],"backgroundTag":"non-serializable-lambda","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"}