apache/dolphinscheduler · error · ServiceException
DELETE_ENVIRONMENT_ERROR
DELETE_ENVIRONMENT_ERROR
Error message
Status.DELETE_ENVIRONMENT_ERROR
What it means
Thrown by EnvironmentServiceImpl.deleteEnvironmentByCode when environmentMapper.deleteByCode returns <= 0 rows after the related-task check passed, meaning the DELETE affected no row. Usually indicates the environment was already deleted concurrently or a database-level failure prevented the delete.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/EnvironmentServiceImpl.java:296
@Transactional
@Override
public void deleteEnvironmentByCode(User loginUser, Long code) {
if (!canOperatorPermissions(loginUser, null, AuthorizationType.ENVIRONMENT, ENVIRONMENT_DELETE)) {
throw new ServiceException(Status.USER_NO_OPERATION_PERM);
}
long relatedTaskNumber = taskDefinitionDao.countByEnvironmentCode(code);
if (relatedTaskNumber > 0) {
log.warn("Delete environment failed because {} tasks is using it, environmentCode:{}.",
relatedTaskNumber, code);
throw new ServiceException(Status.DELETE_ENVIRONMENT_RELATED_TASK_EXISTS);
}
int delete = environmentMapper.deleteByCode(code);
if (delete <= 0) {
log.error("Environment delete error, environmentCode:{}.", code);
throw new ServiceException(Status.DELETE_ENVIRONMENT_ERROR);
}
relationMapper.delete(new QueryWrapper<EnvironmentWorkerGroupRelation>()
.lambda()
.eq(EnvironmentWorkerGroupRelation::getEnvironmentCode, code));
log.info("Environment and relations delete complete, environmentCode:{}.", code);
}
/**
* update environment
*
* @param loginUser login user
* @param code environment code
* @param name environment name
* @param config environment config
* @param desc environment desc
* @param workerGroups worker groups
*/
@TransactionalView on GitHub (pinned to 02eac45a1b)
Solutions
- Verify the environment still exists (queryEnvironmentByCode); if not, treat the delete as already done and ignore this error.
- Retry the delete once after confirming existence.
- Check api-server logs and DB health if the row exists but deletes keep affecting 0 rows.
Example fix
// before
environmentService.deleteEnvironmentByCode(loginUser, code);
// after
try {
environmentService.deleteEnvironmentByCode(loginUser, code);
} catch (ServiceException e) {
if (environmentExists(code)) {
throw e; // real failure
} // else: already deleted concurrently — safe to ignore
} Defensive patterns
Strategy: try-catch
Validate before calling
public void deleteIfPresent(User loginUser, long code) throws ServiceException {
try {
environmentService.queryEnvironmentByCode(code);
} catch (ServiceException gone) {
return; // already deleted
}
environmentService.deleteEnvironmentByCode(loginUser, code);
} Try / catch
try {
environmentService.deleteEnvironmentByCode(loginUser, code);
} catch (ServiceException e) {
if (String.valueOf(e.getMessage()).contains("DELETE_ENVIRONMENT_ERROR")) {
boolean stillExists = true;
try { environmentService.queryEnvironmentByCode(code); } catch (ServiceException gone) { stillExists = false; }
if (!stillExists) return; // concurrent delete won; safe
// otherwise inspect DB, retry with backoff
}
} Prevention
- Serialize environment deletions through a single process or lock to avoid races
- Treat 'delete affected 0 rows' as success when a concurrent delete already removed the row
- Retry once after confirming existence before escalating to DB diagnostics
When it happens
Trigger: Race: another client deletes the same environment between the permission/task checks and the delete statement; DB write failure or constraint causing 0 affected rows; passing a code that vanished mid-transaction.
Common situations: Concurrent cleanup scripts running against the same environment list; UI double-click sending two delete requests where the second fails; DB replica/consistency issues.
Related errors
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/3af6a944c1b6c4b5.
Report an issue: GitHub.