flowable/flowable-engine · error · FlowableIllegalArgumentException

planItemInstanceId is required

Error message

planItemInstanceId is required

What it means

GetHistoricIdentityLinksForPlanItemInstanceCmd fetches historic identity links for a plan item instance. Its constructor throws FlowableIllegalArgumentException when planItemInstanceId is null, per Flowable's uniform constructor validation for commands.

Solutions

  1. Pass a valid non-null planItemInstanceId (e.g. DelegatePlanItemInstance.getId() in listeners).
  2. Validate the id before invoking the history API.
  3. Check you are not mixing up plan item id with stage or case instance id.

Example fix

// before
new GetHistoricIdentityLinksForPlanItemInstanceCmd(variables.get("planItemInstanceId"));
// after
String id = (String) variables.get("planItemInstanceId");
Objects.requireNonNull(id, "planItemInstanceId must be provided");
new GetHistoricIdentityLinksForPlanItemInstanceCmd(id);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(planItemInstanceId, "planItemInstanceId must be provided");

Type guard

boolean hasPlanItemId = p != null && p.getId() != null;

Try / catch

try { ... } catch (FlowableIllegalArgumentException e) { throw new BadRequestException("planItemInstanceId is required"); }

Prevention

When it happens

Trigger: Constructing the command with a null planItemInstanceId, or forwarding a null from a delegate/variable lookup inside a case execution.

Common situations: Plan-item-scoped listeners that read the id from the wrong scope, confusing planItemInstanceId with caseInstanceId or task id.

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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/GetHistoricIdentityLinksForPlanItemInstanceCmd.java:37

import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.api.scope.ScopeTypes;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.identitylink.api.history.HistoricIdentityLink;

/**
 * @author Tijs Rademakers
 */
public class GetHistoricIdentityLinksForPlanItemInstanceCmd implements Command<List<HistoricIdentityLink>>, Serializable {

    private static final long serialVersionUID = 1L;
    
    protected String planItemInstanceId;

    public GetHistoricIdentityLinksForPlanItemInstanceCmd(String planItemInstanceId) {
        if (planItemInstanceId == null) {
            throw new FlowableIllegalArgumentException("planItemInstanceId is required");
        }
        this.planItemInstanceId = planItemInstanceId;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public List<HistoricIdentityLink> execute(CommandContext commandContext) {
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        return (List) cmmnEngineConfiguration.getIdentityLinkServiceConfiguration().getHistoricIdentityLinkService()
                .findHistoricIdentityLinksBySubScopeIdAndScopeType(planItemInstanceId, ScopeTypes.PLAN_ITEM);
    }

}

View on GitHub (pinned to d6d39ce1c6)