{"record":{"id":"6e35e24732f7c6c0","repo":"apache/dolphinscheduler","slug":"the-task-taskname-state-actualstate","errorCode":null,"errorMessage":"\"The task: \" + taskName + \" state: \" + actualState + \" is not match:\" + expectState","messagePattern":"\"The task: \" \\+ taskName \\+ \" state: \" \\+ actualState \\+ \" is not match:\" \\+ expectState","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/task/statemachine/AbstractTaskStateAction.java","lineNumber":296,"sourceCode":"    protected void publishWorkflowInstanceTopologyLogicalTransitionEvent(\n                                                                         final IWorkflowExecution workflowExecution,\n                                                                         final ITaskExecution taskExecution) {\n        taskExecution\n                .getWorkflowEventBus()\n                .publish(\n                        WorkflowTopologyLogicalTransitionWithTaskFinishLifecycleEvent.of(\n                                workflowExecution,\n                                taskExecution));\n    }\n\n    protected void throwExceptionIfStateIsNotMatch(final ITaskExecution taskExecution) {\n        checkNotNull(taskExecution, \"taskExecution is null\");\n        final TaskInstance taskInstance = checkNotNull(taskExecution.getTaskInstance(), \"taskInstance is null\");\n        final TaskExecutionStatus actualState = taskInstance.getState();\n        final TaskExecutionStatus expectState = matchState();\n        if (actualState != expectState) {\n            final String taskName = taskInstance.getName();\n            throw new IllegalStateException(\n                    \"The task: \" + taskName + \" state: \" + actualState + \" is not match:\" + expectState);\n        }\n    }\n\n    protected void logWarningIfCannotDoAction(final ITaskExecution taskExecution,\n                                              final AbstractLifecycleEvent event) {\n        final TaskInstance taskInstance = taskExecution.getTaskInstance();\n        log.warn(\"Task[name={}] state is {} cannot do action on event: {}\",\n                taskInstance.getName(),\n                taskInstance.getState(),\n                event);\n    }\n}\n","sourceCodeStart":278,"sourceCodeEnd":310,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/task/statemachine/AbstractTaskStateAction.java#L278-L310","documentation":"AbstractTaskStateAction.throwExceptionIfStateIsNotMatch enforces that a task state action (e.g. dispatch, pause, kill handlers) is only applied to a task whose TaskInstance state equals matchState(). If the actual TaskExecutionStatus differs, it throws IllegalStateException naming the task and both states. This guards the task state machine against acting on stale or inconsistent task state.","triggerScenarios":"A lifecycle event or state action arrives for a task whose TaskInstance state has already changed (e.g. kill event on a task that already succeeded, dispatch on an already-failed task), so actualState != matchState().","commonSituations":"Race conditions between concurrent events (success event vs kill command); duplicate or delayed events after failover; external modification of task instance state in the DB; event replay for tasks completed earlier.","solutions":["Check the task instance's current state in the UI/DB to see which state transition actually occurred.","Verify no duplicate/out-of-order lifecycle events are being processed (check master logs around the exception).","Make callers gate actions with logWarningIfCannotDoAction / state checks before invoking the state action.","If caused by failover, let the failover logic re-sync task states instead of firing stale events."],"exampleFix":"// before: acting without checking state\nstateAction.handle(taskExecution, event);\n\n// after: guard against state mismatch\nif (taskExecution.getTaskInstance().getState() == expectedState) {\n    stateAction.handle(taskExecution, event);\n} else {\n    log.warn(\"Skip action on task {}: state {} != {}\", taskExecution.getName(),\n        taskExecution.getTaskInstance().getState(), expectedState);\n}","handlingStrategy":"validation","validationCode":"// before invoking a state action\nTaskExecutionStatus actual = taskExecution.getTaskInstance().getState();\nTaskExecutionStatus expected = stateAction.matchState();\nif (actual != expected) {\n    log.warn(\"Skip: task {} state {} does not match {}\", taskExecution.getName(), actual, expected);\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    stateAction.handle(taskExecution, event);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"The task:\")) {\n        log.warn(\"Stale event for task, state mismatch: {}\", e.getMessage());\n    } else { throw e; }\n}","preventionTips":["Always check the task instance state before sending lifecycle actions.","Deduplicate and order events (by event timestamp/state) to avoid races.","Re-sync task states after master failover before replaying queued events."],"tags":["state-machine","illegal-state","task-lifecycle","race-condition"],"backgroundTag":"invalid-state-transition","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"}