apache/dolphinscheduler · warning · ServiceException
DELETE_SCHEDULE_BY_ID_ERROR
DELETE_SCHEDULE_BY_ID_ERROR
Error message
DELETE_SCHEDULE_BY_ID_ERROR: delete schedule by id error
What it means
DELETE_SCHEDULE_BY_ID_ERROR is thrown by deleteSchedulesById when scheduleDao.deleteById(scheduleId) returns false — all prior checks (existence, offline state, ownership, project permission) passed, but the database delete affected no rows. This usually indicates a concurrent delete or a persistence-layer failure.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java:366
@Override
public void deleteSchedulesById(User loginUser, Integer scheduleId) {
Schedule schedule = scheduleDao.queryById(scheduleId);
if (schedule == null) {
throw new ServiceException(Status.SCHEDULE_NOT_EXISTS, scheduleId);
}
// check schedule is already online
if (schedule.getReleaseState() == ReleaseState.ONLINE) {
throw new ServiceException(Status.SCHEDULE_STATE_ONLINE, scheduleId);
}
// Determine if the login user is the owner of the schedule
if (loginUser.getId() != schedule.getUserId() && loginUser.getUserType() != UserType.ADMIN_USER) {
throw new ServiceException(Status.USER_NO_OPERATION_PERM);
}
this.projectPermCheckByWorkflowCode(loginUser, schedule.getWorkflowDefinitionCode());
boolean delete = scheduleDao.deleteById(scheduleId);
if (!delete) {
throw new ServiceException(Status.DELETE_SCHEDULE_BY_ID_ERROR);
}
}
/**
* preview schedule
*
* @param loginUser login user
* @param schedule schedule expression
* @return the next five fire time
*/
@Override
public List<String> previewSchedule(User loginUser, String schedule) {
Cron cron;
ScheduleParam scheduleParam = JSONUtils.parseObject(schedule, ScheduleParam.class);
assert scheduleParam != null;
ZoneId zoneId = TimeZone.getTimeZone(scheduleParam.getTimezoneId()).toZoneId();
ZonedDateTime now = ZonedDateTime.now(zoneId);View on GitHub (pinned to 02eac45a1b)
Solutions
- Re-fetch the schedule; if it no longer exists, treat the delete as already completed and continue.
- Retry the delete once after a short delay to absorb transient DB/lock failures.
- Serialize cleanup jobs (single worker or distributed lock) so two processes cannot delete the same schedule concurrently.
- Check database logs for lock timeouts or rollback causes if the error persists.
Example fix
// before
for id in ids: deleteSchedule(id) // two workers race -> one fails here
// after
with distributed_lock("schedule-cleanup"):
for id in ids: deleteSchedule(id) # skip if GET shows schedule gone Defensive patterns
Strategy: retry
Validate before calling
Schedule s = scheduleDao.queryById(scheduleId);
if (s == null) return; // nothing to delete
boolean deleted = scheduleDao.deleteById(scheduleId);
if (!deleted) { /* retry once, then re-check existence */ } Try / catch
try { schedulerService.deleteSchedulesById(user, scheduleId); } catch (ServiceException e) { if (e.getCode() == Status.DELETE_SCHEDULE_BY_ID_ERROR) { /* re-check existence; if absent, treat as success, else retry with backoff */ } } Prevention
- Serialize schedule deletions with a lock to avoid concurrent deletes
- Add one retry with backoff around schedule deletes
- Monitor DB for lock timeouts; check dao delete affected-row semantics
When it happens
Trigger: DELETE /projects/{projectCode}/schedules/{id} racing with another user/script deleting the same schedule between queryById and deleteById; DB transaction rollback, lock timeout, or constraint failure inside scheduleDao.deleteById.
Common situations: Two operators deleting the same timing in the UI at once; duplicate cleanup cron jobs hitting the API concurrently; database connectivity/lock issues under load; replication lag in read/write split setups where the read saw the row but the write replica had already removed it.
Related errors
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/b9ef1eb10c4590c6.
Report an issue: GitHub.