apache/dolphinscheduler · error · ServiceException

50036

50036

Error message

check workflow task relation error

What it means

Thrown when any WorkflowTaskRelationLog in taskRelationJson has a postTaskCode of 0, meaning the relation's downstream task is unset. Only preTaskCode may be 0 (marking the workflow's entry relation), so a zero post-task makes the relation invalid.

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java:428

                Set<Long> taskNodeCodes = taskNodeList.stream().map(TaskNode::getCode).collect(Collectors.toSet());
                Collection<Long> codes = CollectionUtils.subtract(postTaskCodes, taskNodeCodes);
                if (CollectionUtils.isNotEmpty(codes)) {
                    String taskCodes = StringUtils.join(codes, Constants.COMMA);
                    log.error("Task definitions do not exist, taskCodes:{}.", taskCodes);
                    throw new ServiceException(Status.TASK_DEFINE_NOT_EXIST, taskCodes);
                }
            }
            if (graphHasCycle(taskNodeList)) {
                log.error("workflow DAG has cycle.");
                throw new ServiceException(Status.WORKFLOW_NODE_HAS_CYCLE);
            }

            // check whether the task relation json is normal
            for (WorkflowTaskRelationLog workflowTaskRelationLog : taskRelationList) {
                if (workflowTaskRelationLog.getPostTaskCode() == 0) {
                    log.error("The post_task_code or post_task_version of workflowTaskRelationLog can not be zero, " +
                            "workflowTaskRelationLogId:{}.", workflowTaskRelationLog.getId());
                    throw new ServiceException(Status.CHECK_WORKFLOW_TASK_RELATION_ERROR);
                }
            }
            return taskRelationList;
        } catch (ServiceException ex) {
            throw ex;
        } catch (Exception e) {
            log.error("Check task relation list error, meet an unknown exception, given taskRelationJson: {}",
                    taskRelationJson, e);
            throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR);
        }
    }

    /**
     * query workflow definition list
     *
     * @param loginUser   login user
     * @param projectCode project code
     * @return definition list

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Set postTaskCode to the actual task code of the downstream task for every relation entry
  2. Remove any relation entry that has no real downstream task
  3. Regenerate relation JSON from the saved workflow to get correct codes

Example fix

// before
{"preTaskCode":123,"postTaskCode":0,...}
// after
{"preTaskCode":123,"postTaskCode":456,"postTaskVersion":1}
Defensive patterns

Strategy: validation

Validate before calling

boolean hasZeroPost = relations.stream().anyMatch(r -> r.getPostTaskCode() == 0);
if (hasZeroPost) throw new IllegalArgumentException("postTaskCode cannot be 0");

Try / catch

try { ... } catch (ServiceException e) { if (e.getCode() == 50036) { /* scan relations for postTaskCode==0 */ } }

Prevention

When it happens

Trigger: updateWorkflowDefinition/importWorkflowDefinition with a relation entry where postTaskCode=0 — typically a partially initialized or truncated relation object.

Common situations: Hand-constructing relations JSON and leaving postTaskCode defaulted to 0; copy-pasting the entry relation (pre=0) and swapping fields; JSON tooling that drops numeric fields equal to 0.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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