{"record":{"id":"47abf36273d9aafe","repo":"quarkusio/quarkus","slug":"cannot-modify-a-job-that-was-already-scheduled","errorCode":null,"errorMessage":"Cannot modify a job that was already scheduled","messagePattern":"Cannot modify a job that was already scheduled","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/AbstractJobDefinition.java","lineNumber":152,"sourceCode":"    @Override\n    public THIS setAsyncTask(Function<ScheduledExecution, Uni<Void>> asyncTask) {\n        checkScheduled();\n        if (task != null) {\n            throw new IllegalStateException(\"Sync task was already set\");\n        }\n        this.asyncTask = Objects.requireNonNull(asyncTask);\n        return self();\n    }\n\n    @Override\n    public THIS setAsyncTask(Class<? extends Function<ScheduledExecution, Uni<Void>>> asyncTaskClass) {\n        this.asyncTaskClass = Objects.requireNonNull(asyncTaskClass);\n        return setAsyncTask(SchedulerUtils.instantiateBeanOrClass(asyncTaskClass));\n    }\n\n    protected void checkScheduled() {\n        if (scheduled) {\n            throw new IllegalStateException(\"Cannot modify a job that was already scheduled\");\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    protected THIS self() {\n        return (THIS) this;\n    }\n\n}\n","sourceCodeStart":134,"sourceCodeEnd":162,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/AbstractJobDefinition.java#L134-L162","documentation":"JobDefinition is a fluent, mutable builder whose setters (setCron, setInterval, setDelayed, setConcurrentExecution, setSkipPredicate, setOverdueGracePeriod) are only legal until the job is scheduled. checkScheduled() throws this IllegalStateException once the job has been registered with the scheduler and someone attempts further mutation.","triggerScenarios":"Calling any setter on a JobDefinition after the definition was scheduled (the scheduled flag is set), e.g. keeping a reference and later calling setCron(\"0 0 * * * ?\") to 'update' the job.","commonSituations":"Trying to dynamically reschedule a job through the old definition object instead of the scheduler's update API; caching JobDefinition instances in a service and mutating them at runtime; tests reconfiguring an already-submitted job.","solutions":["To change a scheduled job's config, unschedule and create a new JobDefinition via scheduler.newJob(...) with the updated settings, or use the scheduler's schedule/update flow","Treat JobDefinition as write-once: finish all setters before submitting","Do not store and mutate JobDefinition references after scheduling","For dynamic schedules, use a scheduling implementation that supports job updates (e.g. Quartz-based) and its own APIs"],"exampleFix":"// before\njobDef.setCron(\"0 0 12 * * ?\"); // job already scheduled -> throws\n// after\nscheduler.unscheduleJob(\"j\");\nscheduler.newJob(\"j\").setCron(\"0 0 12 * * ?\").setTask(task).schedule();","handlingStrategy":"validation","validationCode":"if (definition.isScheduled()) { // track via your own wrapper\n    throw new IllegalStateException(\"create a new JobDefinition to change config\");\n}\ndefinition.setCron(newCron);","typeGuard":"boolean modifiable(JobDefinition d) {\n    return !scheduledJobs.contains(d); // maintain registry of scheduled definitions\n}","tryCatchPattern":"try {\n    definition.setCron(newCron);\n} catch (IllegalStateException e) {\n    scheduler.unscheduleJob(id);\n    scheduler.newJob(id).setCron(newCron).setTask(task).schedule();\n}","preventionTips":["Treat JobDefinition as write-once; set everything before scheduling","Never cache/mutate JobDefinition references after submission","Recreate definitions for updates instead of mutating","Encapsulate rescheduling logic in a helper that always builds a fresh definition"],"tags":["scheduler","job-definition","immutability","lifecycle"],"backgroundTag":"illegal-state-after-submit","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"}