flowable/flowable-engine · error · ActivitiIllegalArgumentException

processDefinitionKey and processDefinitionId are null

Error message

processDefinitionKey and processDefinitionId are null

What it means

Thrown by StartProcessInstanceCmd.execute() as ActivitiIllegalArgumentException when neither processDefinitionId nor processDefinitionKey is set, so the command has no way to resolve which process to start. This is a programmer/input error guard at the start of definition resolution.

Solutions

  1. Pass a valid key: runtimeService.startProcessInstanceByKey("orderProcess").
  2. If identifiers come from config/requests, fail fast upstream with a clear validation message when null/blank.
  3. When using ProcessInstantiationBuilder, ensure processDefinitionKey(...) or processDefinitionId(...) is invoked before .start().
  4. Review the caller that produced the null id/key — often an unset environment variable or missing request field.

Example fix

// before
String key = config.get("process.key"); // null
runtimeService.startProcessInstanceByKey(key); // ActivitiIllegalArgumentException
// after
String key = config.get("process.key");
Objects.requireNonNull(key, "process.key must be configured");
runtimeService.startProcessInstanceByKey(key);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(definitionKey, "processDefinitionKey must not be null");
if (definitionKey.isBlank()) {
    throw new IllegalArgumentException("processDefinitionKey must not be blank");
}

Try / catch

if (definitionKey == null || definitionKey.isBlank()) {
    throw new IllegalArgumentException("processDefinitionKey is required");
}
try {
    return runtimeService.startProcessInstanceByKey(definitionKey, vars);
} catch (ActivitiIllegalArgumentException e) {
    throw new IllegalStateException("Engine rejected null definition reference", e);
}

Prevention

When it happens

Trigger: Calling RuntimeService.startProcessInstanceById(null) / startProcessInstanceByKey(null), or building a ProcessInstantiationBuilder without calling processDefinitionId/Key/tenantId before start(); message/CQRS handlers forwarding null definition identifiers.

Common situations: Configuration properties left empty (null definition key from properties/YAML); variables or request DTOs with missing process key fields passed straight into the runtime service; test code instantiating the command directly.

Related errors


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

Appendix: source

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

        // Find the process definition
        ProcessDefinition processDefinition = null;
        if (processDefinitionId != null) {
            processDefinition = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
            if (processDefinition == null) {
                throw new ActivitiObjectNotFoundException("No process definition found for id = '" + processDefinitionId + "'", ProcessDefinition.class);
            }
        } else if (processDefinitionKey != null && (tenantId == null || ProcessEngineConfiguration.NO_TENANT_ID.equals(tenantId))) {
            processDefinition = deploymentManager.findDeployedLatestProcessDefinitionByKey(processDefinitionKey);
            if (processDefinition == null) {
                throw new ActivitiObjectNotFoundException("No process definition found for key '" + processDefinitionKey + "'", ProcessDefinition.class);
            }
        } else if (processDefinitionKey != null && tenantId != null && !ProcessEngineConfiguration.NO_TENANT_ID.equals(tenantId)) {
            processDefinition = deploymentManager.findDeployedLatestProcessDefinitionByKeyAndTenantId(processDefinitionKey, tenantId);
            if (processDefinition == null) {
                throw new ActivitiObjectNotFoundException("No process definition found for key '" + processDefinitionKey + "' for tenant identifier " + tenantId, ProcessDefinition.class);
            }
        } else {
            throw new ActivitiIllegalArgumentException("processDefinitionKey and processDefinitionId are null");
        }

        // Do not start process a process instance if the process definition is suspended
        if (deploymentManager.isProcessDefinitionSuspended(processDefinition.getId())) {
            throw new ActivitiException("Cannot start process instance. Process definition "
                    + processDefinition.getName() + " (id = " + processDefinition.getId() + ") is suspended");
        }

        // Start the process instance
        ExecutionEntity processInstance = ((ProcessDefinitionEntity) processDefinition).createProcessInstance(businessKey);

        // now set the variables passed into the start command
        initializeVariables(processInstance);

        // now set processInstance name
        if (processInstanceName != null) {
            processInstance.setName(processInstanceName);
            commandContext.getHistoryManager().recordProcessInstanceNameChange(processInstance.getId(), processInstanceName);

View on GitHub (pinned to d6d39ce1c6)