Repository navigation
Conversation
…kRelation references missing task definitions When taskRelationJson references a task code that has no matching entry in taskDefinitionJson, ProcessServiceImpl#transformTask throws a NullPointerException which generateTaskRelationList swallows into a generic 10001 REQUEST_PARAMS_NOT_VALID_ERROR. Validate up-front that every pre/post task code referenced by the relations exists in the task definitions and fail fast with TASK_DEFINE_NOT_EXIST naming the missing codes (the same semantics the existing post-code-only size-mismatch check already uses). Also make transformTask null-safe (taskType, pre-task lookup) for its other callers.
|
Thanks for opening this pull request! Please check out our contributing guidelines. (https://github.com/apache/dolphinscheduler/blob/dev/docs/docs/en/contribute/join/pull-request.md) |
SbloodyS
left a comment
There was a problem hiding this comment.
Reject missing predecessors instead of silently removing them
ProcessServiceImpl.java:720 adds filter(Objects::nonNull), turning a relation such as missing A -> existing B into a node B with no predecessors.
The new validation only protects generateTaskRelationList(). WorkflowInstanceServiceImpl calls checkWorkflowNodeList() directly, which uses transformTask() without that validation. The filtered graph now passes validation, and saveTaskRelation() can persist the original dangling relation because it also does not reject missing definitions. Previously, this input failed during transformation.
Please validate missing task references in the shared transformation path and fail explicitly instead of dropping dependencies. Add regression coverage for workflow-instance updates, asserting that the missing code is reported and no invalid relations are persisted.
…d transformation path Per review feedback: filter(Objects::nonNull) silently turned a relation missing A -> existing B into node B without predecessors, and only generateTaskRelationList was guarded - WorkflowInstanceServiceImpl reaches transformTask via checkWorkflowNodeList without any validation, so the filtered graph could pass and saveTaskRelation could persist the dangling relation. - ProcessServiceImpl#transformTask now collects pre task codes without a matching task definition and fails explicitly naming the missing codes (shared path, no more silent edge dropping) - WorkflowDefinitionServiceImpl#checkWorkflowNodeList converts that failure into TASK_DEFINE_NOT_EXIST so workflow-instance updates report the missing code - regression tests: shared transformTask failure, checkWorkflowNodeList conversion, and updateWorkflowInstance asserting the missing code is reported and no invalid relations/definition version are persisted
|
Thanks for the review @SbloodyS — good catch on the silent edge drop. Addressed in 00743a1:
The up-front validation in |
SbloodyS
left a comment
There was a problem hiding this comment.
Please remove the null taskType fallback to an empty string in ProcessServiceImpl#transformTask(). A missing task type is invalid data and should fail explicitly with task identity, rather than producing a TaskNode with an empty type. This fallback is unrelated to the missing-task-code fix.
…tead of empty-string fallback Per review: a missing taskType is invalid data and should fail explicitly with task identity (taskCode/taskName), rather than producing a TaskNode with an empty type. The empty-string fallback is removed; transformTask now throws naming the offending task.
|
Addressed in 5452fb0: the empty-string fallback for a null taskType is removed — |
ruanwenjun
left a comment
There was a problem hiding this comment.
It might be better to throw an invalid DAG status code here, and then specify in the exception message that the task definition is missing.
| try { | ||
| taskNodes = processService.transformTask(taskRelationList, taskDefinitionLogsList); | ||
| } catch (org.apache.dolphinscheduler.service.exceptions.ServiceException e) { | ||
| // transformTask reports task codes referenced by relations but missing in task definitions | ||
| log.error("Task definitions do not exist, given workflowTaskRelationJson: {}", | ||
| workflowTaskRelationJson, e); |
There was a problem hiding this comment.
It's better to throw ServiceException at transformTask rather than wrap all exception into new ServiceException(Status.TASK_DEFINE_NOT_EXIST, e.getMessage());.
…issing task definitions in the message - introduce Status.WORKFLOW_DAG_IS_INVALID(50082) and use it for the relation/definition consistency checks in WorkflowDefinitionServiceImpl, with the message naming the missing task codes, instead of mislabeling every failure as TASK_DEFINE_NOT_EXIST - checkWorkflowNodeList translates transformTask's ServiceException (thrown at transformTask with the precise reason) to WORKFLOW_DAG_IS_INVALID keeping its message, and no longer logs the raw workflowTaskRelationJson in the error path (CodeQL log injection)
|
Thanks for the review @ruanwenjun — addressed in 8cc040c:
|
Was this PR generated or assisted by AI?
YES — the fix, the unit test and this description were drafted with AI assistance (Claude-based coding agent); the bug itself was discovered while driving the DolphinScheduler 3.2.2 REST API from a data-sync pipeline. The change was reviewed, compiled and tested locally by the submitter.
Purpose of the pull request
Fixes #18675
When
taskRelationJsonreferences a task code that has no matching entry intaskDefinitionJson,ProcessServiceImpl#transformTaskthrows aNullPointerException:The NPE is caught by the generic
catch (Exception e)inWorkflowDefinitionServiceImpl#generateTaskRelationListand returned to the client as a generic10001 REQUEST_PARAMS_NOT_VALID_ERRORwith no hint about the real cause. This is easy to hit when building the two JSON payloads programmatically (REST API instead of the UI): any code mismatch between the relations and the definitions on a pre task silently degrades into the generic error.The existing size-mismatch check in
generateTaskRelationListalready returnsTASK_DEFINE_NOT_EXISTfor missing post task codes, but pre-task codes never reach it — the NPE happens first.Brief change log
WorkflowDefinitionServiceImpl#generateTaskRelationList: before callingtransformTask, validate that every pre/post task code referenced by the relations has a matching task definition; throwTASK_DEFINE_NOT_EXIST(50030) naming the missing codes — the same semantics the existing post-code check already uses. This covers both the create and the update path.ProcessServiceImpl#transformTask: make the mapping null-safe (filter(Objects::nonNull)on the pre-task lookup, null-safetaskType) so that other callers of this service method degrade gracefully instead of throwing NPE.Verify this pull request
This change added tests and can be verified as follows:
testCreateWorkflowDefinitionShouldRejectUnknownPreTaskCodetoWorkflowDefinitionServiceTest: a relation referencing an unknownpreTaskCodenow fails fast withTASK_DEFINE_NOT_EXISTand nothing is persisted.mvn -pl dolphinscheduler-api -am test -Dtest=WorkflowDefinitionServiceTestlocally — all tests in the class pass.