apache/dolphinscheduler · error · ServiceException
SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_VERSION_ERROR
SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_VERSION_ERROR
Error message
SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_VERSION_ERROR: switch workflow definition version error because workflow definition version [{1}] of [{0}] does not exist What it means
Thrown by switchWorkflowDefinitionVersion when the workflow definition exists but no WorkflowDefinitionLog row exists for the requested (code, version) pair — i.e. that version was never saved or was purged. workflowDefinitionLogMapper.queryByDefinitionCodeAndVersion returned null, so there is nothing to switch to.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java:1602
Project project = projectDao.queryByCode(projectCode);
projectService.checkHasProjectWritePermissionThrowException(loginUser, project);
WorkflowDefinition workflowDefinition = workflowDefinitionDao.queryByCode(code).orElse(null);
if (Objects.isNull(workflowDefinition) || projectCode != workflowDefinition.getProjectCode()) {
log.error(
"Switch workflow definition error because it does not exist, projectCode:{}, workflowDefinitionCode:{}.",
projectCode, code);
throw new ServiceException(Status.SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_ERROR,
code);
}
WorkflowDefinitionLog workflowDefinitionLog =
workflowDefinitionLogMapper.queryByDefinitionCodeAndVersion(code, version);
if (Objects.isNull(workflowDefinitionLog)) {
log.error(
"Switch workflow definition error because version does not exist, projectCode:{}, workflowDefinitionCode:{}, version:{}.",
projectCode, code, version);
throw new ServiceException(
Status.SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_VERSION_ERROR,
workflowDefinition.getCode(), version);
}
List<WorkflowTaskRelation> workflowTaskRelationList = workflowTaskRelationDao
.queryWorkflowTaskRelationsByWorkflowDefinitionCode(workflowDefinitionLog.getCode(),
workflowDefinitionLog.getVersion());
List<TaskCodeVersionDto> taskDefinitionList = getTaskCodeVersionDtos(workflowTaskRelationList);
List<TaskDefinitionLog> taskDefinitionLogList =
taskDefinitionLogMapper.queryByTaskDefinitions(taskDefinitionList.stream()
.flatMap(taskCodeVersionDto -> {
TaskDefinitionLog taskDefinitionLog = new TaskDefinitionLog();
taskDefinitionLog.setCode(taskCodeVersionDto.getCode());
taskDefinitionLog.setVersion(taskCodeVersionDto.getVersion());
return Stream.of(taskDefinitionLog);
}).collect(Collectors.toList()));
taskDatasourcePermissionChecker.checkPermission(loginUser, taskDefinitionLogList);
taskSubWorkflowPermissionChecker.checkPermission(loginUser, taskDefinitionLogList);
View on GitHub (pinned to 02eac45a1b)
Solutions
- List available versions first (GET .../workflow-definition/{code}/versions) and switch only to a version in that list.
- If the version was purged from t_ds_workflow_definition_log, restore it from a backup or re-save the definition to create a new version.
- Update automation to fetch the latest/existing version dynamically instead of hard-coding version numbers.
- Check DB retention/cleanup settings if versions disappear unexpectedly.
Example fix
// before workflowDefinitionService.switchWorkflowDefinitionVersion(user, projectCode, code, 7); // after Map<String, Object> versions = workflowDefinitionService.queryWorkflowDefinitionVersions(user, projectCode, code, 1, 10, null); int existingVersion = /* pick from versions list */ 3; workflowDefinitionService.switchWorkflowDefinitionVersion(user, projectCode, code, existingVersion);
Defensive patterns
Strategy: validation
Validate before calling
boolean versionExists(long code, int version) {
return workflowDefinitionLogMapper.queryByDefinitionCodeAndVersion(code, version) != null;
}
// or via API: GET /projects/{projectCode}/workflow-definition/{code}/versions before switching Try / catch
try {
workflowDefinitionService.switchWorkflowDefinitionVersion(user, projectCode, code, version);
} catch (ServiceException e) {
if (e.getCode() == Status.SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_VERSION_ERROR) {
// fetch available versions and pick an existing one
}
} Prevention
- Always list available versions via the versions API before switching.
- Never hard-code version numbers in scripts; read the latest/available version dynamically.
- Check DB cleanup/retention jobs if historical versions disappear from t_ds_workflow_definition_log.
When it happens
Trigger: Calling the version-switch endpoint with a version number that was never created for the workflow (e.g. version 5 when only 1-3 exist), or a version that was removed by log cleanup/DB pruning.
Common situations: Hard-coding version numbers in scripts; DB housekeeping jobs or manual cleanup deleted t_ds_workflow_definition_log rows; querying a workflow cloned into a new project where history did not carry over.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- SWITCH_WORKFLOW_DEFINITION_VERSION_NOT_EXIST_WORKFLOW_DEFINITION_ERROR
- SCHEDULE_NOT_EXISTS
- WORKFLOW_DEFINITION_NOT_EXIST
- 10001
- The execType: {execType} is invalid
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/d016dcb481fcd49c.
Report an issue: GitHub.