quarkusio/quarkus · error · IllegalStateException
Either sync or async task must be set
Error message
Either sync or async task must be set
What it means
`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.
Source
Thrown at extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java:906
"A task instance cannot be scheduled programmatically if DB store type is used; register a task class instead");
}
return super.setTask(task, runOnVirtualThread);
}
@Override
public QuartzJobDefinition setAsyncTask(Function<ScheduledExecution, Uni<Void>> asyncTask) {
if (storeType.isDbStore() && asyncTaskClass == null) {
throw new IllegalStateException(
"An async task instance cannot be scheduled programmatically if DB store type is used; register an async task class instead");
}
return super.setAsyncTask(asyncTask);
}
@Override
public Trigger schedule() {
checkScheduled();
if (task == null && asyncTask == null) {
throw new IllegalStateException("Either sync or async task must be set");
}
scheduled = true;
SyntheticScheduled scheduled = new SyntheticScheduled(identity, cron, every, 0, TimeUnit.MINUTES, delayed,
overdueGracePeriod, concurrentExecution, skipPredicate, timeZone, implementation, executionMaxDelay,
description);
return createJobDefinitionQuartzTrigger(this, scheduled, null);
}
}
interface ExecutionMetadata {
Consumer<ScheduledExecution> task();
Class<? extends Consumer<ScheduledExecution>> taskClass();
Function<ScheduledExecution, Uni<Void>> asyncTask();
View on GitHub (pinned to e1c734241f)
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
Example fix
// before
scheduler.newJob("nightly").setCron("0 0 2 * * ?").schedule();
// after
scheduler.newJob("nightly").setCron("0 0 2 * * ?").setTask(e -> runNightly()).schedule(); Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(task, "task");
Objects.requireNonNull(asyncTask, "asyncTask");
if (task == null && asyncTask == null) throw new IllegalStateException("set task before schedule"); Try / catch
try { def.schedule(); } catch (IllegalStateException e) { log.error("Job {} incomplete: {}", identity, e.getMessage()); } Prevention
- 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()
When it happens
Trigger: Calling `scheduler.newJob("id").setCron(...)...schedule()` without ever calling setTask/setAsyncTask (only e.g. setSkipPredicate or setTaskClass-related metadata set but no task).
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid schedule configuration: {scheduled}
- A job with this identity is already scheduled: {identity}
- One of either visitorFunction or inputTransformer must be se
- name cannot be null
- Predicate already set
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/69e7a7e4e745c365.
Report an issue: GitHub.