flowable/flowable-engine · error · FlowableIllegalArgumentException

Case instance id is required

Error message

Case instance id is required

What it means

After confirming the builder has at least one operation, ChangePlanItemStateCmd validates that a case instance id was set. A null caseInstanceId makes the command unresolvable, so Flowable throws FlowableIllegalArgumentException("Case instance id is required").

Solutions

  1. Pass the actual case instance id to createChangePlanItemStateBuilder(caseInstanceId).
  2. Resolve the id first, e.g. via cmmnRuntimeService.createCaseInstanceQuery().processInstanceBusinessKey(...).singleResult().getId(), checking for null.
  3. Add an early guard in the caller that rejects empty case instance ids with a clearer message.

Example fix

// before
String caseInstanceId = caseInstance != null ? caseInstance.getId() : null;
cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId)
    .activatePlanItemDefinition("task1").changeState();

// after
if (caseInstance == null) throw new IllegalArgumentException("case instance not found");
cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstance.getId())
    .activatePlanItemDefinition("task1").changeState();
Defensive patterns

Strategy: validation

Validate before calling

if (caseInstanceId == null || caseInstanceId.isBlank()) throw new IllegalArgumentException("caseInstanceId is required for plan item state change");

Try / catch

try { builder.changeState(); } catch (FlowableIllegalArgumentException e) { /* missing case instance id */ }

Prevention

When it happens

Trigger: Calling createChangePlanItemStateBuilder(null) or a ChangePlanItemStateBuilder constructed without setCaseInstanceId, then invoking changeState().

Common situations: Passing a variable holding the case instance id that was never resolved (null from a prior query); refactored code dropping the id parameter; building the command from a request where caseInstanceId was optional and missing.

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

Appendix: source

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

    protected ChangePlanItemStateBuilderImpl changePlanItemStateBuilder;

    public ChangePlanItemStateCmd(ChangePlanItemStateBuilderImpl changePlanItemStateBuilder, CmmnEngineConfiguration cmmnEngineConfiguration) {
        this.changePlanItemStateBuilder = changePlanItemStateBuilder;
        this.cmmnEngineConfiguration = cmmnEngineConfiguration;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (changePlanItemStateBuilder.getActivatePlanItemDefinitions().size() == 0 &&
                changePlanItemStateBuilder.getTerminatePlanItemDefinitions().size() == 0 &&
                changePlanItemStateBuilder.getChangeToAvailableStatePlanItemDefinitions().size() == 0 &&
                changePlanItemStateBuilder.getWaitingForRepetitionPlanItemDefinitions().size() == 0 &&
                changePlanItemStateBuilder.getRemoveWaitingForRepetitionPlanItemDefinitions().size() == 0) {
            
            throw new FlowableIllegalArgumentException("No move plan item instance or (activate) plan item definition ids provided");

        } else if (changePlanItemStateBuilder.getCaseInstanceId() == null) {
            throw new FlowableIllegalArgumentException("Case instance id is required");   
        }

        CmmnDynamicStateManager dynamicStateManager = cmmnEngineConfiguration.getDynamicStateManager();
        dynamicStateManager.movePlanItemInstanceState(changePlanItemStateBuilder, commandContext);

        return null;
    }
}

View on GitHub (pinned to d6d39ce1c6)