apache/dolphinscheduler · error · IllegalStateException

"The task: " + taskName + " state: " + actualState + " is no

Error message

"The task: " + taskName + " state: " + actualState + " is not match:" + expectState

What it means

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.

Source

Thrown at dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/task/statemachine/AbstractTaskStateAction.java:296

    protected void publishWorkflowInstanceTopologyLogicalTransitionEvent(
                                                                         final IWorkflowExecution workflowExecution,
                                                                         final ITaskExecution taskExecution) {
        taskExecution
                .getWorkflowEventBus()
                .publish(
                        WorkflowTopologyLogicalTransitionWithTaskFinishLifecycleEvent.of(
                                workflowExecution,
                                taskExecution));
    }

    protected void throwExceptionIfStateIsNotMatch(final ITaskExecution taskExecution) {
        checkNotNull(taskExecution, "taskExecution is null");
        final TaskInstance taskInstance = checkNotNull(taskExecution.getTaskInstance(), "taskInstance is null");
        final TaskExecutionStatus actualState = taskInstance.getState();
        final TaskExecutionStatus expectState = matchState();
        if (actualState != expectState) {
            final String taskName = taskInstance.getName();
            throw new IllegalStateException(
                    "The task: " + taskName + " state: " + actualState + " is not match:" + expectState);
        }
    }

    protected void logWarningIfCannotDoAction(final ITaskExecution taskExecution,
                                              final AbstractLifecycleEvent event) {
        final TaskInstance taskInstance = taskExecution.getTaskInstance();
        log.warn("Task[name={}] state is {} cannot do action on event: {}",
                taskInstance.getName(),
                taskInstance.getState(),
                event);
    }
}

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Check the task instance's current state in the UI/DB to see which state transition actually occurred.
  2. Verify no duplicate/out-of-order lifecycle events are being processed (check master logs around the exception).
  3. Make callers gate actions with logWarningIfCannotDoAction / state checks before invoking the state action.
  4. If caused by failover, let the failover logic re-sync task states instead of firing stale events.

Example fix

// before: acting without checking state
stateAction.handle(taskExecution, event);

// after: guard against state mismatch
if (taskExecution.getTaskInstance().getState() == expectedState) {
    stateAction.handle(taskExecution, event);
} else {
    log.warn("Skip action on task {}: state {} != {}", taskExecution.getName(),
        taskExecution.getTaskInstance().getState(), expectedState);
}
Defensive patterns

Strategy: validation

Validate before calling

// before invoking a state action
TaskExecutionStatus actual = taskExecution.getTaskInstance().getState();
TaskExecutionStatus expected = stateAction.matchState();
if (actual != expected) {
    log.warn("Skip: task {} state {} does not match {}", taskExecution.getName(), actual, expected);
    return;
}

Try / catch

try {
    stateAction.handle(taskExecution, event);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("The task:")) {
        log.warn("Stale event for task, state mismatch: {}", e.getMessage());
    } else { throw e; }
}

Prevention

When it happens

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

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

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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