apache/dolphinscheduler · warning · ServiceException

taskDepMsg.get()

Error message

taskDepMsg.get()

What it means

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.

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkflowLineageController.java:139

     */
    @Operation(summary = "verifyTaskCanDelete", description = "VERIFY_TASK_CAN_DELETE")
    @Parameters({
            @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true, schema = @Schema(implementation = long.class)),
            @Parameter(name = "workflowDefinitionCode", description = "WORKFLOW_DEFINITION_CODE", required = true, schema = @Schema(implementation = long.class)),
            @Parameter(name = "taskCode", description = "TASK_DEFINITION_CODE", required = true, schema = @Schema(implementation = long.class, example = "123456789")),
    })
    @PostMapping(value = "/tasks/verify-delete")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(TASK_WITH_DEPENDENT_ERROR)
    public Result<Map<String, Object>> verifyTaskCanDelete(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                                           @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
                                                           @RequestParam(value = "workflowDefinitionCode") long workflowDefinitionCode,
                                                           @RequestParam(value = "taskCode") long taskCode) {
        Result<Map<String, Object>> result = new Result<>();
        Optional<String> taskDepMsg =
                workflowLineageService.taskDependentMsg(loginUser, projectCode, workflowDefinitionCode, taskCode);
        if (taskDepMsg.isPresent()) {
            throw new ServiceException(taskDepMsg.get());
        }
        putMsg(result, Status.SUCCESS);
        return result;
    }

    /**
     * Whether task can be deleted or not, avoiding task depend on other task of workflow definition delete by accident.
     */
    @Operation(summary = "verifyTaskCanDelete", description = "VERIFY_TASK_CAN_DELETE")
    @Parameters({
            @Parameter(name = "projectCode", description = "WORKFLOW_DEFINITION_NAME", required = true, schema = @Schema(implementation = long.class)),
            @Parameter(name = "workFlowCode", description = "WORKFLOW_DEFINITION_CODE", required = true, schema = @Schema(implementation = long.class)),
    })
    @GetMapping(value = "/query-dependent-tasks")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_WORKFLOW_LINEAGE_ERROR)
    public Result<Map<String, Object>> queryDependentTasks(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                                           @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Read the thrown message: it names the dependent workflows/tasks — delete or rewire those dependents first.
  2. Re-parent dependent tasks so they no longer reference this task, then retry the delete.
  3. If the dependency info is stale, recompute lineage (re-save affected workflows) and retry.

Example fix

// before: delete directly
deleteTask(projectCode, taskCode);
// after: guard via the lineage check
Result r = verifyTaskCanDelete(loginUser, projectCode, workflowCode, taskCode);
if (!r.isSuccess()) { /* resolve dependents reported in r.getMsg() first */ }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check dependents before deletion
Optional<String> depMsg = workflowLineageService.taskDependentMsg(loginUser, projectCode, workflowCode, taskCode);
if (depMsg.isPresent()) {
    // resolve dependents named in depMsg.get() before deleting
    return;
}

Try / catch

try {
    lineageController.verifyTaskCanDelete(loginUser, projectCode, workflowCode, taskCode);
} catch (ServiceException e) {
    log.warn("Task deletion blocked by lineage: {} — remove dependents first", e.getMessage());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/12a06cf5e4ab21f9. Report an issue: GitHub.