{"record":{"id":"12a06cf5e4ab21f9","repo":"apache/dolphinscheduler","slug":"taskdepmsg-get","errorCode":null,"errorMessage":"taskDepMsg.get()","messagePattern":"taskDepMsg\\.get\\(\\)","errorType":"exception","errorClass":"ServiceException","httpStatus":null,"severity":"warning","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkflowLineageController.java","lineNumber":139,"sourceCode":"     */\n    @Operation(summary = \"verifyTaskCanDelete\", description = \"VERIFY_TASK_CAN_DELETE\")\n    @Parameters({\n            @Parameter(name = \"projectCode\", description = \"PROJECT_CODE\", required = true, schema = @Schema(implementation = long.class)),\n            @Parameter(name = \"workflowDefinitionCode\", description = \"WORKFLOW_DEFINITION_CODE\", required = true, schema = @Schema(implementation = long.class)),\n            @Parameter(name = \"taskCode\", description = \"TASK_DEFINITION_CODE\", required = true, schema = @Schema(implementation = long.class, example = \"123456789\")),\n    })\n    @PostMapping(value = \"/tasks/verify-delete\")\n    @ResponseStatus(HttpStatus.OK)\n    @ApiException(TASK_WITH_DEPENDENT_ERROR)\n    public Result<Map<String, Object>> verifyTaskCanDelete(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,\n                                                           @Parameter(name = \"projectCode\", description = \"PROJECT_CODE\", required = true) @PathVariable long projectCode,\n                                                           @RequestParam(value = \"workflowDefinitionCode\") long workflowDefinitionCode,\n                                                           @RequestParam(value = \"taskCode\") long taskCode) {\n        Result<Map<String, Object>> result = new Result<>();\n        Optional<String> taskDepMsg =\n                workflowLineageService.taskDependentMsg(loginUser, projectCode, workflowDefinitionCode, taskCode);\n        if (taskDepMsg.isPresent()) {\n            throw new ServiceException(taskDepMsg.get());\n        }\n        putMsg(result, Status.SUCCESS);\n        return result;\n    }\n\n    /**\n     * Whether task can be deleted or not, avoiding task depend on other task of workflow definition delete by accident.\n     */\n    @Operation(summary = \"verifyTaskCanDelete\", description = \"VERIFY_TASK_CAN_DELETE\")\n    @Parameters({\n            @Parameter(name = \"projectCode\", description = \"WORKFLOW_DEFINITION_NAME\", required = true, schema = @Schema(implementation = long.class)),\n            @Parameter(name = \"workFlowCode\", description = \"WORKFLOW_DEFINITION_CODE\", required = true, schema = @Schema(implementation = long.class)),\n    })\n    @GetMapping(value = \"/query-dependent-tasks\")\n    @ResponseStatus(HttpStatus.OK)\n    @ApiException(QUERY_WORKFLOW_LINEAGE_ERROR)\n    public Result<Map<String, Object>> queryDependentTasks(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,\n                                                           @Parameter(name = \"projectCode\", description = \"PROJECT_CODE\", required = true) @PathVariable long projectCode,","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkflowLineageController.java#L121-L157","documentation":"WorkflowLineageController.verifyTaskCanDelete asks workflowLineageService.taskDependentMsg for a dependency-blocking reason. The Optional message is only present when the task cannot be safely deleted (other workflow tasks depend on it); in that case the message is wrapped in ServiceException and thrown. 'taskDepMsg.get()' is just the source expression — the thrown text is the lineage service's dependency description.","triggerScenarios":"DELETE /lineage/{projectCode}/verify-task-can-delete (or equivalent) for a task whose code is referenced by dependent/derived tasks in other workflow definitions, i.e. taskLineage returned non-empty dependent info.","commonSituations":"Attempting to clean up a shared/dimension task used by downstream workflows; deleting tasks as part of workflow refactoring without first removing dependents; scripting bulk deletions without dependency checks.","solutions":["Read the thrown message: it names the dependent workflows/tasks — delete or rewire those dependents first.","Re-parent dependent tasks so they no longer reference this task, then retry the delete.","If the dependency info is stale, recompute lineage (re-save affected workflows) and retry."],"exampleFix":"// before: delete directly\ndeleteTask(projectCode, taskCode);\n// after: guard via the lineage check\nResult r = verifyTaskCanDelete(loginUser, projectCode, workflowCode, taskCode);\nif (!r.isSuccess()) { /* resolve dependents reported in r.getMsg() first */ }","handlingStrategy":"try-catch","validationCode":"// Pre-check dependents before deletion\nOptional<String> depMsg = workflowLineageService.taskDependentMsg(loginUser, projectCode, workflowCode, taskCode);\nif (depMsg.isPresent()) {\n    // resolve dependents named in depMsg.get() before deleting\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    lineageController.verifyTaskCanDelete(loginUser, projectCode, workflowCode, taskCode);\n} catch (ServiceException e) {\n    log.warn(\"Task deletion blocked by lineage: {} — remove dependents first\", e.getMessage());\n}","preventionTips":["Always call verifyTaskCanDelete before deleting a task.","Treat shared/downstream tasks (dimension-layer tasks) as delete-restricted.","Maintain an inventory of inter-workflow task dependencies."],"tags":["rest-api","lineage","task-dependency","delete-blocked"],"backgroundTag":"resource-not-found","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"}