flowable/flowable-engine · error · FlowableIllegalArgumentException

The command is null

Error message

The command is null

What it means

Null check in CmmnManagementServiceImpl.executeCommand(Command): the command argument is null so nothing can be executed. This is the escape hatch for running arbitrary custom Commands against the CMMN engine.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/CmmnManagementServiceImpl.java:345

    
    @Override
    public void unacquireAllExternalWorkerJobsForWorker(String workerId) {
        commandExecutor.execute(new UnacquireAllExternalWorkerJobsForWorkerCmd(workerId, null, configuration.getJobServiceConfiguration()));
    }
    
    @Override
    public void unacquireAllExternalWorkerJobsForWorker(String workerId, String tenantId) {
        commandExecutor.execute(new UnacquireAllExternalWorkerJobsForWorkerCmd(workerId, tenantId, configuration.getJobServiceConfiguration()));
    }
    
    @Override
    public ChangeTenantIdBuilder createChangeTenantIdBuilder(String fromTenantId, String toTenantId) {
        return new ChangeTenantIdBuilderImpl(fromTenantId, toTenantId, configuration.getChangeTenantIdManager());
    }

    public <T> T executeCommand(Command<T> command) {
        if (command == null) {
            throw new FlowableIllegalArgumentException("The command is null");
        }
        return commandExecutor.execute(command);
    }

    public <T> T executeCommand(CommandConfig config, Command<T> command) {
        if (config == null) {
            throw new FlowableIllegalArgumentException("The config is null");
        }
        if (command == null) {
            throw new FlowableIllegalArgumentException("The command is null");
        }
        return commandExecutor.execute(config, command);
    }
    
    @Override
    public LockManager getLockManager(String lockName) {
        return new LockManagerImpl(commandExecutor, lockName, getConfiguration().getLockPollRate(), configuration.getEngineCfgKey());
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a non-null Command instance; check whatever builds the command for null-returning paths
  2. Guard the call site: if (command != null) cmmnManagementService.executeCommand(command)
  3. Fix the command factory to throw its own descriptive error instead of returning null

Example fix

// before
Command<MyResult> cmd = buildCommand(ctx);
cmmnManagementService.executeCommand(cmd);
// after
Command<MyResult> cmd = buildCommand(ctx);
Objects.requireNonNull(cmd, "command must not be null");
cmmnManagementService.executeCommand(cmd);
Defensive patterns

Strategy: validation

Validate before calling

if (command == null) throw new IllegalArgumentException("command required");

Try / catch

try { managementService.executeCommand(cmd); } catch (FlowableIllegalArgumentException e) { /* null command */ }

Prevention

When it happens

Trigger: Calling cmmnManagementService.executeCommand(null); commonly a factory method returning null when building the Command.

Common situations: Building commands conditionally and passing the result straight in; a helper that returns null on a missing tenant/config; unit tests passing uninitialized command variables.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/7086cbab2240eb2d. Report an issue: GitHub.