{"record":{"id":"20d7f2ddc61ee348","repo":"apache/dolphinscheduler","slug":"delete-workflow-lineage-error","errorCode":"DELETE_WORKFLOW_LINEAGE_ERROR","errorMessage":"DELETE_WORKFLOW_LINEAGE_ERROR: delete workflow lineage error","messagePattern":"DELETE_WORKFLOW_LINEAGE_ERROR: delete workflow lineage error","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java","lineNumber":919,"sourceCode":"        // delete task definition\n        taskDefinitionService.deleteTaskByWorkflowDefinitionCode(workflowDefinition.getCode(),\n                workflowDefinition.getVersion());\n        // delete task definition log\n        taskDefinitionLogService.deleteTaskByWorkflowDefinitionCode(workflowDefinition.getCode());\n        // delete workflow definition log\n        workflowDefinitionLogDao.deleteByWorkflowDefinitionCode(workflowDefinition.getCode());\n\n        // we delete the workflow definition at last to avoid using transaction here.\n        // If delete error, we can call this interface again.\n        workflowDefinitionDao.deleteByWorkflowDefinitionCode(workflowDefinition.getCode());\n\n        // delete workflow lineage (lineage data only keeps one record per workflow code)\n        // It's safe to return 0 if no lineage exists (idempotent)\n        int deleteWorkflowLineageResult = workflowLineageService\n                .deleteWorkflowLineage(Collections.singletonList(workflowDefinition.getCode()));\n        if (deleteWorkflowLineageResult <= 0) {\n            if (deleteWorkflowLineageResult < 0) {\n                throw new ServiceException(Status.DELETE_WORKFLOW_LINEAGE_ERROR);\n            } else {\n                log.warn(\"No workflow lineage to delete, workflowDefinitionCode: {}\", code);\n            }\n        }\n        log.info(\"Success delete workflow definition workflowDefinitionCode: {}\", code);\n    }\n\n    /**\n     * check the workflow task relation json\n     *\n     * @param workflowTaskRelationJson workflow task relation json\n     * @return check result code\n     */\n    @Override\n    public void checkWorkflowNodeList(String workflowTaskRelationJson,\n                                      List<TaskDefinitionLog> taskDefinitionLogsList) {\n        try {\n            if (workflowTaskRelationJson == null) {","sourceCodeStart":901,"sourceCodeEnd":937,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java#L901-L937","documentation":"Thrown when workflowLineageService.deleteWorkflowLineage returns a negative value, signaling the lineage deletion for the workflow code failed at the persistence layer. A return of 0 is tolerated (no lineage existed) with only a warning.","triggerScenarios":"The lineage table delete statement fails or reports an error for the workflow's code during deleteWorkflowDefinitionByCode — e.g. DB error, lock timeout, or lineage DAO returning -1 on exception.","commonSituations":"Metadata DB contention during bulk deletes; lineage table corruption or missing permissions; failed transactions leaving lineage rows locked.","solutions":["Inspect the service/DB logs for the underlying lineage delete failure and resolve the database issue.","Retry the deletion after the DB recovers.","Manually delete the orphaned lineage row for the workflow code, then verify the workflow record state."],"exampleFix":"// before\nint r = workflowLineageService.deleteWorkflowLineage(List.of(code));\nif (r < 0) throw new ServiceException(Status.DELETE_WORKFLOW_LINEAGE_ERROR);\n// after (retry with backoff)\nint r = 0;\nfor (int i = 0; i < 3; i++) {\n    r = workflowLineageService.deleteWorkflowLineage(List.of(code));\n    if (r >= 0) break;\n    Thread.sleep(1000L * (i + 1));\n}\nif (r < 0) throw new ServiceException(Status.DELETE_WORKFLOW_LINEAGE_ERROR);","handlingStrategy":"retry","validationCode":"// ensure DB reachable and no open transaction holds the lineage row\nboolean dbUp = dataSource.getConnection().isValid(3);","typeGuard":null,"tryCatchPattern":"try { service.deleteWorkflowDefinitionByCode(user, code); }\ncatch (ServiceException e) { /* transient DB issue: retry with backoff, tolerate r==0 as no-op */ }","preventionTips":["Treat 0-row lineage deletes as normal (idempotent)","Retry transient DB failures with backoff","Avoid bulk deletes that lock the lineage table"],"tags":["lineage","database","delete-failed"],"backgroundTag":"database-write-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"}