{"record":{"id":"90687ff6a8766e83","repo":"flowable/flowable-engine","slug":"a-non-null-value-is-required-for-one-of-timedate","errorCode":null,"errorMessage":"A non-null value is required for one of timeDate, timeDuration, or timeCycle","messagePattern":"A non-null value is required for one of timeDate, timeDuration, or timeCycle","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/RescheduleTimerJobCmd.java","lineNumber":45,"sourceCode":"public class RescheduleTimerJobCmd implements Command<TimerJobEntity>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n\n    private final String timerJobId;\n    private String timeDate;\n    private String timeDuration;\n    private String timeCycle;\n    private String endDate;\n    private String calendarName;\n\n    public RescheduleTimerJobCmd(String timerJobId, String timeDate, String timeDuration, String timeCycle, String endDate, String calendarName) {\n        if (timerJobId == null) {\n            throw new FlowableIllegalArgumentException(\"The timer job id is mandatory, but 'null' has been provided.\");\n        }\n\n        int timeValues = Collections.frequency(Arrays.asList(timeDate, timeDuration, timeCycle), null);\n        if (timeValues == 0) {\n            throw new FlowableIllegalArgumentException(\"A non-null value is required for one of timeDate, timeDuration, or timeCycle\");\n        } else if (timeValues != 2) {\n            throw new FlowableIllegalArgumentException(\"At most one non-null value can be provided for timeDate, timeDuration, or timeCycle\");\n        }\n\n        if (endDate != null && timeCycle == null) {\n            throw new FlowableIllegalArgumentException(\"An end date can only be provided when rescheduling a timer using timeDuration.\");\n        }\n\n        this.timerJobId = timerJobId;\n        this.timeDate = timeDate;\n        this.timeDuration = timeDuration;\n        this.timeCycle = timeCycle;\n        this.endDate = endDate;\n        this.calendarName = calendarName;\n    }\n\n    @Override\n    public TimerJobEntity execute(CommandContext commandContext) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/RescheduleTimerJobCmd.java#L27-L63","documentation":"RescheduleTimerJobCmd accepts exactly one of timeDate, timeDuration, or timeCycle as the new timer value. The constructor counts the non-null values among them: if all three are null (count 0) it throws this error, and if more than one is provided (count != 2 nulls, i.e. 2+ non-null) it throws a related error. Exactly one value must be supplied.","triggerScenarios":"Calling managementService.rescheduleTimeDateJob/rescheduleTimeDurationJob/rescheduleTimeCycleJob with a null/empty time value, or constructing RescheduleTimerJobCmd directly with all three of timeDate, timeDuration, timeCycle set to null — e.g. reading the new schedule from config where the key was missing.","commonSituations":"Schedule values sourced from properties/environment where the expected key (e.g. cron expression) is absent; generic rescheduling helper methods that pass through whichever parameter the caller set, with the caller setting none; refactoring renamed config keys so the lookup yields null.","solutions":["Supply exactly one of timeDate (ISO date), timeDuration (ISO 8601 duration), or timeCycle (cron/repeat) as a non-null string.","Validate the schedule value before calling; if it comes from config, check for presence and provide a default.","Fix config loading so the time value key resolves correctly, and avoid passing empty strings where null checks are used."],"exampleFix":"// before\nmanagementService.rescheduleTimeCycleJob(timerJobId, schedule, null, null, null); // schedule == null\n// after\nObjects.requireNonNull(schedule, \"timeCycle schedule must be configured\");\nmanagementService.rescheduleTimeCycleJob(timerJobId, schedule, null, null, null);","handlingStrategy":"validation","validationCode":"boolean hasExactlyOne = (timeDate != null ? 1 : 0) + (timeDuration != null ? 1 : 0) + (timeCycle != null ? 1 : 0) == 1;\nif (!hasExactlyOne) {\n    throw new IllegalStateException(\"Provide exactly one of timeDate, timeDuration, or timeCycle\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    managementService.rescheduleTimeCycleJob(timerJobId, timeCycle, null, null, null);\n} catch (FlowableIllegalArgumentException e) {\n    // no (or multiple) time value(s) supplied; fall back to configured default schedule\n}","preventionTips":["Validate schedule values come from non-null config before invoking the reschedule API.","Build rescheduling helpers around a single discriminated parameter instead of three nullable ones.","Provide default schedules in configuration so missing keys never surface as null arguments."],"tags":["flowable","timer-job","mutually-exclusive","reschedule"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}