apache/dolphinscheduler · error · java.lang.IllegalArgumentException

The WorkflowFailoverCommandParam: ${commandParam} is invalid

Error message

The WorkflowFailoverCommandParam: ${commandParam} is invalid

What it means

WorkflowFailoverCommandHandler.assembleWorkflowInstance parses the failover command's commandParam JSON into WorkflowFailoverCommandParam; if JSONUtils.parseObject returns null (empty, malformed, or non-matching JSON), this IllegalArgumentException is thrown because failover cannot proceed without the execution status carried in the param.

Source

Thrown at dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/command/handler/WorkflowFailoverCommandHandler.java:86

     *     <li>command type</li>
     *     <li>start time</li>
     *     <li>restart time</li>
     *     <li>end time</li>
     *     <li>run times</li>
     * </ul>
     */
    @Override
    protected void assembleWorkflowInstance(
                                            final WorkflowExecuteContextBuilder workflowExecuteContextBuilder) {
        final Command command = workflowExecuteContextBuilder.getCommand();
        final int workflowInstanceId = command.getWorkflowInstanceId();
        final WorkflowInstance workflowInstance = workflowInstanceDao.queryOptionalById(workflowInstanceId)
                .orElseThrow(() -> new IllegalArgumentException("Cannot find WorkflowInstance:" + workflowInstanceId));
        final WorkflowFailoverCommandParam workflowFailoverCommandParam = JSONUtils.parseObject(
                command.getCommandParam(),
                WorkflowFailoverCommandParam.class);
        if (workflowFailoverCommandParam == null) {
            throw new IllegalArgumentException(
                    "The WorkflowFailoverCommandParam: " + command.getCommandParam() + " is invalid");
        }
        workflowInstance.setRestartTime(new Date());
        workflowInstance.setState(workflowFailoverCommandParam.getWorkflowExecutionStatus());
        workflowInstance.setHost(masterConfig.getMasterAddress());
        workflowInstanceDao.updateById(workflowInstance);

        workflowExecuteContextBuilder.setWorkflowInstance(workflowInstance);
    }

    /**
     * Generate the workflow execution graph.
     * <p> Will rebuild the WorkflowExecutionGraph from the exist task instance.
     */
    @Override
    protected void assembleWorkflowExecutionGraph(final WorkflowExecuteContextBuilder workflowExecuteContextBuilder) {
        final Map<String, TaskInstance> taskInstanceMap =
                getValidTaskInstance(workflowExecuteContextBuilder.getWorkflowInstance())

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Inspect the t_ds_command row for the failing command and verify command_param is valid JSON like {"workflowInstanceId":..., "workflowExecutionStatus":...}
  2. Delete or fix the malformed failover command row so master stops retrying it
  3. Re-trigger failover through the supported failover path instead of crafting commands manually

Example fix

// before (bad command_param)
{"instanceId": 123}
// after
{"workflowInstanceId": 123, "workflowExecutionStatus": "RUNNING_EXECUTION"}
Defensive patterns

Strategy: validation

Validate before calling

String param = command.getCommandParam();
if (param == null || param.isEmpty() || JSONUtils.parseObject(param, WorkflowFailoverCommandParam.class) == null) {
    // reject before processing
}

Type guard

boolean isValidFailoverParam(String json) {
    return json != null && JSONUtils.parseObject(json, WorkflowFailoverCommandParam.class) != null;
}

Try / catch

try {
    handler.handleCommand(command);
} catch (IllegalArgumentException e) {
    log.error("Dropping invalid failover command: {}", e.getMessage());
    commandDao.deleteCommand(command.getId()); // avoid infinite retry
}

Prevention

When it happens

Trigger: A WorkflowFailoverCommand whose commandParam is null, empty string, invalid JSON, or valid JSON lacking the fields needed to deserialize into WorkflowFailoverCommandParam.

Common situations: Commands produced by older versions with a different param schema, manual DB inserts into t_ds_command with wrong command_param, or corruption of the command table.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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