flowable/flowable-engine · error · FlowableIllegalArgumentException

The command is null

Error message

The command is null

What it means

ManagementServiceImpl.executeCommand runs an arbitrary Command through the engine's commandExecutor. The library throws FlowableIllegalArgumentException immediately when the command parameter is null, because there is nothing to execute and executing a null command would fail later with a less clear NPE. It is a fail-fast argument contract for the programmatic command API.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ManagementServiceImpl.java:423

        CommandConfig config = commandExecutor.getDefaultConfig().transactionNotSupported();
        return commandExecutor.execute(config, new Command<>() {
            @Override
            public String execute(CommandContext commandContext) {
                DbSqlSessionFactory dbSqlSessionFactory = (DbSqlSessionFactory) commandContext.getSessionFactories().get(DbSqlSession.class);
                DbSqlSession dbSqlSession = new DbSqlSession(dbSqlSessionFactory, CommandContextUtil.getEntityCache(commandContext), connection, catalog,
                        schema);
                commandContext.getSessions().put(DbSqlSession.class, dbSqlSession);
                ProcessEngineConfigurationImpl engineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
                engineConfiguration.getCommonSchemaManager().schemaUpdate();
                return engineConfiguration.getSchemaManager().schemaUpdate();
            }
        });
    }

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

    @Override
    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 to executeCommand, e.g. managementService.executeCommand(new MyCustomCommand())
  2. Check the code path producing the Command object for early returns of null or failed initialization
  3. Null-check before calling: if (cmd != null) { ... executeCommand(cmd) }
  4. Wrap the call in try-catch for FlowableIllegalArgumentException to surface a clear message in batch/admin tooling

Example fix

// before
Command<String> cmd = buildCommand(cfg); // may return null
String result = managementService.executeCommand(cmd);
// after
Command<String> cmd = buildCommand(cfg);
if (cmd == null) {
    throw new IllegalStateException("command could not be built");
}
String result = managementService.executeCommand(cmd);
Defensive patterns

Strategy: type-guard

Validate before calling

if (command == null) { throw new IllegalArgumentException("command must be provided"); }
managementService.executeCommand(command);

Type guard

boolean isValidCommand(Command<?> c) { return c != null; }

Try / catch

try {
    T result = managementService.executeCommand(command);
} catch (FlowableIllegalArgumentException e) {
    log.error("Invalid command argument: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling managementService.executeCommand(null), e.g. when the Command instance was built conditionally, returned null from a factory/helper method, or a variable holding the command was never initialized.

Common situations: Developers wrapping custom commands whose construction can fail and return null; refactoring that removed command instantiation; tests passing null to verify validation; Spring wiring issues leaving a command supplier returning null.

Related errors


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