{"record":{"id":"637209cf12e2848e","repo":"apache/dolphinscheduler","slug":"workflow-definition-cannot-be-deleted-because-it-h","errorCode":null,"errorMessage":"workflow definition cannot be deleted because it has dependent, {dependent task message}","messagePattern":"workflow definition cannot be deleted because it has dependent, (.+?)","errorType":"exception","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java","lineNumber":867,"sourceCode":"            throw new ServiceException(Status.WORKFLOW_DEFINE_STATE_ONLINE, workflowDefinition.getName());\n        }\n\n        // check workflow instances is already running\n        List<WorkflowInstanceSummaryDto> workflowInstances =\n                workflowInstanceService.queryByWorkflowDefinitionCodeAndStatus(\n                        workflowDefinition.getCode(), WorkflowExecutionStatus.NOT_TERMINAL_STATES);\n        if (CollectionUtils.isNotEmpty(workflowInstances)) {\n            throw new ServiceException(Status.DELETE_WORKFLOW_DEFINITION_EXECUTING_FAIL, workflowInstances.size());\n        }\n\n        // check workflow used by other task, including sub workflow and dependent task type\n        Optional<String> taskDepMsg = workflowLineageService.taskDependentMsg(loginUser,\n                workflowDefinition.getProjectCode(), workflowDefinition.getCode(), 0);\n\n        if (taskDepMsg.isPresent()) {\n            String errorMeg = \"workflow definition cannot be deleted because it has dependent, \" + taskDepMsg.get();\n            log.error(errorMeg);\n            throw new ServiceException(errorMeg);\n        }\n    }\n\n    public void deleteWorkflowDefinitionByCode(User loginUser, long code) {\n        WorkflowDefinition workflowDefinition = workflowDefinitionDao.queryByCode(code)\n                .orElseThrow(() -> new ServiceException(WORKFLOW_DEFINITION_NOT_EXIST, String.valueOf(code)));\n\n        Project project = projectDao.queryByCode(workflowDefinition.getProjectCode());\n        projectService.checkHasProjectWritePermissionThrowException(loginUser, project);\n\n        // Determine if the login user is the owner of the workflow definition\n        if (loginUser.getId() != workflowDefinition.getUserId() && loginUser.getUserType() != UserType.ADMIN_USER) {\n            throw new ServiceException(Status.USER_NO_OPERATION_PERM);\n        }\n\n        workflowDefinitionUsedInOtherTaskValid(loginUser, workflowDefinition);\n\n        // get the timing according to the workflow definition","sourceCodeStart":849,"sourceCodeEnd":885,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java#L849-L885","documentation":"Thrown (with a plain message string, no Status code) when workflowLineageService.taskDependentMsg reports that other tasks — sub-workflow or dependent task types in other workflows — reference this workflow. Deleting would break those dependents, so deletion is refused with the dependent-task message appended.","triggerScenarios":"Deleting a workflow that is used as a sub-workflow or referenced by a DEPENDENT task in another workflow in the same project (or cross-project, per lineage check).","commonSituations":"Retiring a shared child workflow that many parent workflows call; refactoring without updating dependent tasks; tenant/project merges leaving cross references.","solutions":["Read the dependent-task message to find which workflows/tasks reference this one.","Remove or re-point the DEPENDENT / SUB_WORKFLOW tasks that reference it, then delete again.","Delete the referencing parent workflows first if they are also being retired."],"exampleFix":"// before\nservice.deleteWorkflowDefinitionByCode(loginUser, childCode); // has dependents\n// after\nOptional<String> dep = workflowLineageService.taskDependentMsg(loginUser, projectCode, childCode, 0);\nif (dep.isPresent()) {\n    // update or delete the dependent tasks listed in dep.get() first\n}\nservice.deleteWorkflowDefinitionByCode(loginUser, childCode);","handlingStrategy":"validation","validationCode":"Optional<String> dep = workflowLineageService.taskDependentMsg(user, projectCode, code, 0);\nif (dep.isPresent()) {\n    throw new IllegalStateException(\"remove dependents first: \" + dep.get());\n}","typeGuard":null,"tryCatchPattern":"try { service.deleteWorkflowDefinitionByCode(user, code); }\ncatch (ServiceException e) { /* parse dependent task list from e.getMessage() and remove those references */ }","preventionTips":["Run the lineage/dependency check before deleting shared workflows","Track sub-workflow usage in your own metadata","Retire dependents in topological order (children last)"],"tags":["workflow-definition","lineage","dependency"],"backgroundTag":"unsupported-operation","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}