{"record":{"id":"2f64e3e2aa6e8c79","repo":"apache/dolphinscheduler","slug":"start-time-bigger-than-end-time-error","errorCode":"START_TIME_BIGGER_THAN_END_TIME_ERROR","errorMessage":"START_TIME_BIGGER_THAN_END_TIME_ERROR: start time must be smaller than end time","messagePattern":"START_TIME_BIGGER_THAN_END_TIME_ERROR: start time must be smaller than end time","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java","lineNumber":163,"sourceCode":"\n        Schedule scheduleObj = new Schedule();\n        Date now = new Date();\n\n        tenantExistValidator.validate(tenantCode);\n\n        scheduleObj.setTenantCode(tenantCode);\n        scheduleObj.setProjectName(project.getName());\n        scheduleObj.setWorkflowDefinitionCode(workflowDefinitionCode);\n        scheduleObj.setWorkflowDefinitionName(workflowDefinition.getName());\n\n        ScheduleParam scheduleParam = JSONUtils.parseObject(schedule, ScheduleParam.class);\n        if (DateUtils.differSec(scheduleParam.getStartTime(), scheduleParam.getEndTime()) == 0) {\n            log.warn(\"The start time must not be the same as the end or time can not be null.\");\n            throw new ServiceException(Status.SCHEDULE_START_TIME_END_TIME_SAME);\n        }\n        if (scheduleParam.getStartTime().getTime() > scheduleParam.getEndTime().getTime()) {\n            log.warn(\"The start time must smaller than end time\");\n            throw new ServiceException(Status.START_TIME_BIGGER_THAN_END_TIME_ERROR);\n        }\n\n        scheduleObj.setStartTime(scheduleParam.getStartTime());\n        scheduleObj.setEndTime(scheduleParam.getEndTime());\n        if (!CronUtils.isValidExpression(scheduleParam.getCrontab())) {\n            log.error(\"Schedule crontab verify failure, crontab:{}.\", scheduleParam.getCrontab());\n            throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, scheduleParam.getCrontab());\n        }\n        scheduleObj.setCrontab(scheduleParam.getCrontab());\n        validateMissedFirePolicy(scheduleParam);\n        scheduleObj.setMissedFirePolicy(scheduleParam.getMissedFirePolicy());\n        scheduleObj.setTimezoneId(scheduleParam.getTimezoneId());\n        scheduleObj.setWarningType(warningType);\n        scheduleObj.setWarningGroupId(warningGroupId);\n        scheduleObj.setFailureStrategy(failureStrategy);\n        scheduleObj.setCreateTime(now);\n        scheduleObj.setUpdateTime(now);\n        scheduleObj.setUserId(loginUser.getId());","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java#L145-L181","documentation":"START_TIME_BIGGER_THAN_END_TIME_ERROR is thrown by insertSchedule when ScheduleParam.startTime is strictly after ScheduleParam.endTime. A schedule window must run forward in time; DolphinScheduler rejects inverted ranges before creating the quartz schedule. Note the check uses raw getTime(), so it runs after the equality check (differSec == 0).","triggerScenarios":"POST /projects/{projectCode}/schedule with a schedule JSON such as {\"startTime\":\"2026-09-05 00:00:00\",\"endTime\":\"2026-09-01 00:00:00\"}; same happens in updateSchedule when the new expression's times are inverted.","commonSituations":"Swapped date fields in a script or curl command; copy-paste of a template with a later start than end; timezone offsets applied to only one of the two fields; UI date pickers that allow arbitrary ordering.","solutions":["Swap the values so startTime <= endTime, keeping them at least one second apart.","Pre-validate: parse both dates and assert start.getTime() < end.getTime() before invoking the API.","Check whether a timezoneId/timezone conversion is shifting one timestamp; express both in the same zone."],"exampleFix":"// before\n{\"startTime\":\"2026-09-05 00:00:00\",\"endTime\":\"2026-09-01 00:00:00\"}\n// after\n{\"startTime\":\"2026-09-01 00:00:00\",\"endTime\":\"2026-09-05 00:00:00\"}","handlingStrategy":"validation","validationCode":"Date start = sdf.parse(param.getStartTime());\nDate end = sdf.parse(param.getEndTime());\nif (!start.before(end)) {\n    throw new IllegalArgumentException(\"startTime must be earlier than endTime\");\n}","typeGuard":null,"tryCatchPattern":"try { schedulerService.insertSchedule(...); } catch (ServiceException e) { if (e.getCode() == Status.START_TIME_BIGGER_THAN_END_TIME_ERROR) { /* swap or correct the range */ } }","preventionTips":["Use date-range pickers that enforce end > start","Apply timezone conversion to both fields consistently","Assert start.getTime() < end.getTime() in API client code before calling"],"tags":["scheduler","validation","date-range"],"backgroundTag":"invalid-argument-value","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}