{"record":{"id":"69e7a7e4e745c365","repo":"quarkusio/quarkus","slug":"either-sync-or-async-task-must-be-set","errorCode":null,"errorMessage":"Either sync or async task must be set","messagePattern":"Either sync or async task must be set","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java","lineNumber":906,"sourceCode":"                        \"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(\n                        \"An async task instance cannot be scheduled programmatically if DB store type is used; register an async task class instead\");\n            }\n            return super.setAsyncTask(asyncTask);\n        }\n\n        @Override\n        public Trigger schedule() {\n            checkScheduled();\n            if (task == null && asyncTask == null) {\n                throw new IllegalStateException(\"Either sync or async task must be set\");\n            }\n            scheduled = true;\n            SyntheticScheduled scheduled = new SyntheticScheduled(identity, cron, every, 0, TimeUnit.MINUTES, delayed,\n                    overdueGracePeriod, concurrentExecution, skipPredicate, timeZone, implementation, executionMaxDelay,\n                    description);\n            return createJobDefinitionQuartzTrigger(this, scheduled, null);\n        }\n\n    }\n\n    interface ExecutionMetadata {\n\n        Consumer<ScheduledExecution> task();\n\n        Class<? extends Consumer<ScheduledExecution>> taskClass();\n\n        Function<ScheduledExecution, Uni<Void>> asyncTask();\n","sourceCodeStart":888,"sourceCodeEnd":924,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java#L888-L924","documentation":"`QuartzJobDefinitionImpl.schedule()` refuses to schedule a definition that has neither a synchronous task (`setTask`) nor an asynchronous task (`setAsyncTask`). The job would have nothing to execute, so an IllegalStateException is thrown before creating the Quartz trigger.","triggerScenarios":"Calling `scheduler.newJob(\"id\").setCron(...)...schedule()` without ever calling setTask/setAsyncTask (only e.g. setSkipPredicate or setTaskClass-related metadata set but no task).","commonSituations":"Builder-chain refactors dropping the setTask call; conditional code that sets the task on some paths but not others; copying a job definition template without filling in the task.","solutions":["Add a task to the definition before schedule(): `.setTask(exec -> ...)` or `.setAsyncTask(exec -> ...)`","If a class was intended, ensure setTaskClass/setAsyncTaskClass is actually resolving into a task, or call the instance variant directly","Assert in dev tests that every programmatic job definition sets a task"],"exampleFix":"// before\nscheduler.newJob(\"nightly\").setCron(\"0 0 2 * * ?\").schedule();\n// after\nscheduler.newJob(\"nightly\").setCron(\"0 0 2 * * ?\").setTask(e -> runNightly()).schedule();","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(task, \"task\");\nObjects.requireNonNull(asyncTask, \"asyncTask\");\nif (task == null && asyncTask == null) throw new IllegalStateException(\"set task before schedule\");","typeGuard":null,"tryCatchPattern":"try { def.schedule(); } catch (IllegalStateException e) { log.error(\"Job {} incomplete: {}\", identity, e.getMessage()); }","preventionTips":["Build job definitions through a single factory that always sets a task","Use fluent chains without early returns that skip setTask","Unit test every job definition before schedule()"],"tags":["quarkus","quartz","programming-error","builder"],"backgroundTag":"missing-required-argument","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}