flowable/flowable-engine · error · FlowableIllegalArgumentException

planItemInstanceId is null

Error message

planItemInstanceId is null

What it means

GetPlanItemVariableInstanceCmd first validates planItemInstanceId and throws FlowableIllegalArgumentException if it is null. This is an argument-validation error thrown in execute() before any entity lookup. The command is used by plan-item variable APIs returning a VariableInstance object.

Source

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

import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.variable.api.persistence.entity.VariableInstance;

public class GetPlanItemVariableInstanceCmd implements Command<VariableInstance>, Serializable {

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

    public GetPlanItemVariableInstanceCmd(String planItemInstanceId, String variableName) {
        this.planItemInstanceId = planItemInstanceId;
        this.variableName = variableName;
    }

    @Override
    public VariableInstance execute(CommandContext commandContext) {
        if (planItemInstanceId == null) {
            throw new FlowableIllegalArgumentException("planItemInstanceId is null");
        }
        if (variableName == null) {
            throw new FlowableIllegalArgumentException("variableName is null");
        }

        PlanItemInstanceEntity planItemInstance = CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).findById(planItemInstanceId);

        if (planItemInstance == null) {
            throw new FlowableObjectNotFoundException("plan item instance " + planItemInstanceId + " doesn't exist", PlanItemInstance.class);
        }

        return planItemInstance.getVariableInstance(variableName, false);
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Supply a resolved, non-null plan item instance id to the API.
  2. Add requireNonNull assertions in caller code before the engine call.
  3. Ensure listeners/processors skip plan items without ids rather than calling the API.
  4. Check argument order and payload mapping for the call.

Example fix

// before
VariableInstance vi = cmmnRuntimeService.getPlanItemVariableInstance(planItemId, varName);
// after
if (planItemId == null) { throw new IllegalArgumentException("planItemId required"); }
VariableInstance vi = cmmnRuntimeService.getPlanItemVariableInstance(planItemId, varName);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(planItemInstanceId, "planItemInstanceId is required");

Type guard

boolean hasPlanItemId(String id) { return id != null && !id.trim().isEmpty(); }

Try / catch

try {
    vi = cmmnRuntimeService.getPlanItemVariableInstance(planItemInstanceId, variableName);
} catch (FlowableIllegalArgumentException e) {
    log.warn("Invalid plan item variable lookup arguments");
    vi = null;
}

Prevention

When it happens

Trigger: Calling getPlanItemVariableInstance(planItemInstanceId, variableName) style APIs with null id — e.g. variable resolvers invoked for plan items that never got instantiated, or delegation code dropping the id.

Common situations: Custom variable listeners/resolvers called with partial context; templated API calls where the id placeholder was empty; misordered arguments passing variableName first.

Related errors


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