flowable/flowable-engine · error · FlowableIllegalArgumentException

The process definition id is mandatory, but '${processDefini

Error message

The process definition id is mandatory, but '${processDefinitionId}' has been provided.

What it means

setProcessDefinitionId in GetFormKeyCmd throws FlowableIllegalArgumentException when the processDefinitionId is null or empty. The constructor calls this setter, so passing a missing process definition id to new GetFormKeyCmd fails immediately with this message.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetFormKeyCmd.java:56

     */
    public GetFormKeyCmd(String processDefinitionId) {
        setProcessDefinitionId(processDefinitionId);
    }

    /**
     * Retrieves a task form key.
     */
    public GetFormKeyCmd(String processDefinitionId, String taskDefinitionKey) {
        setProcessDefinitionId(processDefinitionId);
        if (taskDefinitionKey == null || taskDefinitionKey.length() < 1) {
            throw new FlowableIllegalArgumentException("The task definition key is mandatory, but '" + taskDefinitionKey + "' has been provided.");
        }
        this.taskDefinitionKey = taskDefinitionKey;
    }

    protected void setProcessDefinitionId(String processDefinitionId) {
        if (processDefinitionId == null || processDefinitionId.length() < 1) {
            throw new FlowableIllegalArgumentException("The process definition id is mandatory, but '" + processDefinitionId + "' has been provided.");
        }
        this.processDefinitionId = processDefinitionId;
    }

    @Override
    public String execute(CommandContext commandContext) {
        ProcessDefinition processDefinition = ProcessDefinitionUtil.getProcessDefinition(processDefinitionId);

        if (Flowable5Util.isFlowable5ProcessDefinition(processDefinition, commandContext)) {
            return Flowable5Util.getFlowable5CompatibilityHandler().getFormKey(processDefinitionId, taskDefinitionKey);
        }

        FormHandlerHelper formHandlerHelper = CommandContextUtil.getProcessEngineConfiguration(commandContext).getFormHandlerHelper();
        DefaultFormHandler formHandler;
        if (taskDefinitionKey == null) {
            // TODO: Maybe add getFormKey() to FormHandler interface to avoid the following cast
            formHandler = (DefaultFormHandler) formHandlerHelper.getStartFormHandler(commandContext, processDefinition);
        } else {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Only construct GetFormKeyCmd for tasks that belong to a process (check task.getProcessDefinitionId() != null first).
  2. Pass the id resolved via taskService/identity of the running task rather than a possibly-empty variable.
  3. Handle standalone tasks by returning a null/absent form key instead of calling the command.

Example fix

// before
String formKey = taskService.getTaskFormKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
// after
String formKey = task.getProcessDefinitionId() != null
    ? taskService.getTaskFormKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey())
    : null;
Defensive patterns

Strategy: validation

Validate before calling

if (processDefinitionId == null || processDefinitionId.isEmpty()) {
    return null;
}

Type guard

boolean hasProcessDefinitionId(TaskInfo t) { return t.getProcessDefinitionId() != null && !t.getProcessDefinitionId().isEmpty(); }

Try / catch

try {
    return taskService.getTaskFormKey(processDefinitionId, taskDefinitionKey);
} catch (FlowableIllegalArgumentException e) {
    return null;
}

Prevention

When it happens

Trigger: new GetFormKeyCmd(null, taskDefinitionKey) or with "" — commonly when the process definition id is derived from a task's processDefinitionId property that is null for standalone tasks, or an empty variable/parameter at the call site.

Common situations: Resolving form keys for standalone tasks (created via TaskService without a process) where getProcessDefinitionId() returns null; wiring form-key resolution generically over both standalone and process tasks.

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/b3949ad4088d3c8a. Report an issue: GitHub.