{"record":{"id":"ba38adf00a1d4579","repo":"apache/dolphinscheduler","slug":"10140","errorCode":"10140","errorMessage":"parse cron to cron expression error","messagePattern":"parse cron to cron expression error","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java","lineNumber":552,"sourceCode":"                                    FailureStrategy failureStrategy, Priority workflowInstancePriority,\n                                    String workerGroup, String tenantCode, long environmentCode) {\n        if (schedule.getReleaseState() == ReleaseState.ONLINE) {\n            log.warn(\"Schedule can not be updated due to schedule is {}, scheduleId:{}.\",\n                    ReleaseState.ONLINE.getDescp(), schedule.getId());\n            throw new ServiceException(Status.SCHEDULE_CRON_ONLINE_FORBID_UPDATE);\n        }\n\n        Date now = new Date();\n\n        tenantExistValidator.validate(tenantCode);\n        schedule.setTenantCode(tenantCode);\n\n        // updateWorkflowInstance param\n        if (!StringUtils.isEmpty(scheduleExpression)) {\n            ScheduleParam scheduleParam = JSONUtils.parseObject(scheduleExpression, ScheduleParam.class);\n            if (scheduleParam == null) {\n                log.warn(\"Parameter scheduleExpression is invalid, so parse cron error.\");\n                throw new ServiceException(Status.PARSE_TO_CRON_EXPRESSION_ERROR);\n            }\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            schedule.setStartTime(scheduleParam.getStartTime());\n            schedule.setEndTime(scheduleParam.getEndTime());\n            if (!CronUtils.isValidExpression(scheduleParam.getCrontab())) {\n                log.error(\"Schedule crontab verify failure, crontab:{}.\", scheduleParam.getCrontab());\n                throw new ServiceException(Status.SCHEDULE_CRON_CHECK_FAILED, scheduleParam.getCrontab());\n            }\n            schedule.setCrontab(scheduleParam.getCrontab());\n            validateMissedFirePolicy(scheduleParam);","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java#L534-L570","documentation":"During updateSchedule, the scheduleExpression JSON string is deserialized into a ScheduleParam; when the string is non-empty but does not parse (or yields an empty object), JSONUtils.parseObject returns null and PARSE_TO_CRON_EXPRESSION_ERROR is thrown. It indicates the scheduleExpression payload is not the expected JSON shape.","triggerScenarios":"Passing a scheduleExpression that is non-empty but invalid JSON (truncated, quoted wrongly), or valid JSON missing required fields so the resulting ScheduleParam is null/unusable.","commonSituations":"API clients sending the crontab string directly instead of a JSON object like {\"startTime\":..., \"endTime\":..., \"crontab\":\"...\"}; shell scripts with broken quoting; encoding issues mangling the JSON.","solutions":["Send scheduleExpression as a valid ScheduleParam JSON object with startTime, endTime, and crontab fields.","Validate the JSON with a parser/linter before calling the API.","Check shell quoting and escaping when building the request from scripts.","Omit the parameter entirely (empty string) if you do not want to change the schedule expression, rather than sending garbage."],"exampleFix":"// before\nString scheduleExpression = \"0 0 12 * * ?\";              // raw cron, not JSON\n\n// after\nString scheduleExpression = \"{\\\"startTime\\\":1690000000000,\\\"endTime\\\":1890000000000,\\\"crontab\\\":\\\"0 0 12 * * ?\\\"}\";","handlingStrategy":"validation","validationCode":"JSONUtils.parseObject(scheduleExpression, ScheduleParam.class); // assert non-null before calling\nif (JSONUtils.parseObject(scheduleExpression, ScheduleParam.class) == null) {\n    throw new IllegalArgumentException(\"scheduleExpression is not valid ScheduleParam JSON\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    schedulerService.updateSchedule(loginUser, projectCode, id, scheduleExpression, ...);\n} catch (ServiceException e) {\n    if (e.getCode() == Status.PARSE_TO_CRON_EXPRESSION_ERROR.getCode()) {\n        // fix scheduleExpression JSON shape: {startTime, endTime, crontab}\n    }\n}","preventionTips":["Always send scheduleExpression as a JSON object with startTime/endTime/crontab","Validate JSON with a parser before submitting from scripts","Mind shell quoting/escaping when building JSON inline","Use a typed DTO and serialize it rather than hand-writing JSON strings"],"tags":["json","deserialization","scheduler","invalid-payload"],"backgroundTag":"json-unmarshal-failed","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"}