flowable/flowable-engine · error · ActivitiIllegalArgumentException

process definition id is null

Error message

process definition id is null

What it means

SaveProcessDefinitionInfoCmd stores extra JSON info (an infoNode) attached to a process definition, and rejects a null processDefinitionId with ActivitiIllegalArgumentException before any entity lookup. The id is the key that ties the info record to the definition, so it is mandatory.

Source

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

/**
 * @author Tijs Rademakers
 */
public class SaveProcessDefinitionInfoCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;

    protected String processDefinitionId;
    protected ObjectNode infoNode;

    public SaveProcessDefinitionInfoCmd(String processDefinitionId, ObjectNode infoNode) {
        this.processDefinitionId = processDefinitionId;
        this.infoNode = infoNode;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (processDefinitionId == null) {
            throw new ActivitiIllegalArgumentException("process definition id is null");
        }

        if (infoNode == null) {
            throw new ActivitiIllegalArgumentException("process definition info node is null");
        }

        ProcessDefinitionInfoEntityManager definitionInfoEntityManager = commandContext.getProcessDefinitionInfoEntityManager();
        ProcessDefinitionInfoEntity definitionInfoEntity = definitionInfoEntityManager.findProcessDefinitionInfoByProcessDefinitionId(processDefinitionId);
        if (definitionInfoEntity == null) {
            definitionInfoEntity = new ProcessDefinitionInfoEntity();
            definitionInfoEntity.setProcessDefinitionId(processDefinitionId);
            commandContext.getProcessDefinitionInfoEntityManager().insertProcessDefinitionInfo(definitionInfoEntity);
        } else {
            commandContext.getProcessDefinitionInfoEntityManager().updateProcessDefinitionInfo(definitionInfoEntity);
        }

        try {
            ObjectWriter writer = commandContext.getProcessEngineConfiguration().getObjectMapper().writer();

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Resolve the processDefinitionId explicitly (repositoryService.createProcessDefinitionQuery()...singleResult().getId()) before saving.
  2. Null-check the id at the calling layer and surface a validation error to the user.
  3. Fix the upstream lookup that produced the null id rather than defaulting it.

Example fix

// before
repositoryService.saveProcessDefinitionInfo(processDefinitionId, infoNode);

// after
if (processDefinitionId == null) {
    throw new IllegalArgumentException("processDefinitionId is required");
}
repositoryService.saveProcessDefinitionInfo(processDefinitionId, infoNode);
Defensive patterns

Strategy: validation

Validate before calling

if (processDefinitionId == null || processDefinitionId.isEmpty()) throw new IllegalArgumentException("processDefinitionId is required");

Type guard

boolean canSaveInfo(String id, JsonNode node) { return id != null && !id.isEmpty() && node != null; }

Try / catch

try {
    repositoryService.saveProcessDefinitionInfo(id, infoNode);
} catch (ActivitiIllegalArgumentException e) {
    throw new BadRequestException("processDefinitionId is required");
}

Prevention

When it happens

Trigger: repositoryService.saveProcessDefinitionInfo(null, infoNode), commonly because the definition id came from an optional request parameter, a lookup that returned null, or an uninitialized field.

Common situations: Admin tooling saving definition metadata from a form where the definition was never selected; code refactors dropping the id argument; scripts iterating definitions where one lookup returned null.

Related errors


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