flowable/flowable-engine · error · ActivitiIllegalArgumentException

Process definition id or key cannot be null

Error message

Process definition id or key cannot be null

What it means

AbstractSetProcessDefinitionStateCmd.findProcessDefinition() validates that at least one of processDefinitionId or processDefinitionKey is set before querying. If both are null (ActivitiIllegalArgumentException is thrown). The command (suspend/activate process definition) cannot locate any definition without one of these identifiers.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AbstractSetProcessDefinitionStateCmd.java:93

            createTimerForDelayedExecution(commandContext, processDefinitions);
        } else { // Process definition state is changed now
            changeProcessDefinitionState(commandContext, processDefinitions);
        }

        return null;
    }

    protected List<ProcessDefinitionEntity> findProcessDefinition(CommandContext commandContext) {

        // If process definition is already provided (eg. when command is called through the DeployCmd)
        // we don't need to do an extra database fetch and we can simply return it, wrapped in a list
        if (processDefinitionEntity != null) {
            return Collections.singletonList(processDefinitionEntity);
        }

        // Validation of input parameters
        if (processDefinitionId == null && processDefinitionKey == null) {
            throw new ActivitiIllegalArgumentException("Process definition id or key cannot be null");
        }

        List<ProcessDefinitionEntity> processDefinitionEntities = new ArrayList<>();
        ProcessDefinitionEntityManager processDefinitionManager = commandContext.getProcessDefinitionEntityManager();

        if (processDefinitionId != null) {

            ProcessDefinitionEntity processDefinitionEntity = processDefinitionManager.findProcessDefinitionById(processDefinitionId);
            if (processDefinitionEntity == null) {
                throw new ActivitiObjectNotFoundException("Cannot find process definition for id '" + processDefinitionId + "'", ProcessDefinition.class);
            }
            processDefinitionEntities.add(processDefinitionEntity);

        } else {

            ProcessDefinitionQueryImpl query = new ProcessDefinitionQueryImpl(commandContext).processDefinitionKey(processDefinitionKey);

            if (tenantId == null || ProcessEngineConfiguration.NO_TENANT_ID.equals(tenantId)) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass processDefinitionId (activateProcessDefinitionById / suspendProcessDefinitionById) when the exact definition id is known.
  2. Otherwise pass processDefinitionKey (activateProcessDefinitionByKey / suspendProcessDefinitionByKey).
  3. Validate your input map/request: ensure the identifier parameter is not being lost or misnamed before invoking the API.
  4. Ensure you are not shadowing the id/key fields with null defaults when constructing the command.

Example fix

// before
repositoryService.suspendProcessDefinition(new SuspendProcessDefinitionCmd(null, null, false, null, null));
// after
repositoryService.suspendProcessDefinitionByKey("orderProcess");
Defensive patterns

Strategy: validation

Validate before calling

if (id == null && key == null) { throw new IllegalArgumentException("Provide processDefinitionId or processDefinitionKey"); }

Try / catch

try { repositoryService.suspendProcessDefinition(id, key, false, null, tenantId); } catch (ActivitiIllegalArgumentException e) { if (e.getMessage().contains("id or key cannot be null")) { throw new IllegalArgumentException("caller must supply id or key"); } throw e; }

Prevention

When it happens

Trigger: Calling SetProcessDefinitionStateCmd-derived commands (e.g. repositoryService.activateProcessDefinition()/suspendProcessDefinition()) with neither the id nor the key supplied.

Common situations: Programmatic suspension/activation built dynamically where both parameters end up null; custom code constructing the command object without setting fields; passing only unrelated query parameters.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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