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 listView on GitHub (pinned to 02eac45a1b)
Solutions
- Set postTaskCode to the actual task code of the downstream task for every relation entry
- Remove any relation entry that has no real downstream task
- 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
- Only preTaskCode may be 0 (entry relation)
- Check that JSON tooling doesn't drop or default numeric fields
- Copy relation templates carefully — don't swap pre/post
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.