{"record":{"id":"aa77d973aac9722a","repo":"flowable/flowable-engine","slug":"no-move-plan-item-instance-or-activate-plan-item","errorCode":null,"errorMessage":"No move plan item instance or (activate) plan item definition ids provided","messagePattern":"No move plan item instance or \\(activate\\) plan item definition ids provided","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ChangePlanItemStateCmd.java","lineNumber":45,"sourceCode":"\n    protected CmmnEngineConfiguration cmmnEngineConfiguration;\n    \n    protected ChangePlanItemStateBuilderImpl changePlanItemStateBuilder;\n\n    public ChangePlanItemStateCmd(ChangePlanItemStateBuilderImpl changePlanItemStateBuilder, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        this.changePlanItemStateBuilder = changePlanItemStateBuilder;\n        this.cmmnEngineConfiguration = cmmnEngineConfiguration;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        if (changePlanItemStateBuilder.getActivatePlanItemDefinitions().size() == 0 &&\n                changePlanItemStateBuilder.getTerminatePlanItemDefinitions().size() == 0 &&\n                changePlanItemStateBuilder.getChangeToAvailableStatePlanItemDefinitions().size() == 0 &&\n                changePlanItemStateBuilder.getWaitingForRepetitionPlanItemDefinitions().size() == 0 &&\n                changePlanItemStateBuilder.getRemoveWaitingForRepetitionPlanItemDefinitions().size() == 0) {\n            \n            throw new FlowableIllegalArgumentException(\"No move plan item instance or (activate) plan item definition ids provided\");\n\n        } else if (changePlanItemStateBuilder.getCaseInstanceId() == null) {\n            throw new FlowableIllegalArgumentException(\"Case instance id is required\");   \n        }\n\n        CmmnDynamicStateManager dynamicStateManager = cmmnEngineConfiguration.getDynamicStateManager();\n        dynamicStateManager.movePlanItemInstanceState(changePlanItemStateBuilder, commandContext);\n\n        return null;\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":57,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ChangePlanItemStateCmd.java#L27-L57","documentation":"ChangePlanItemStateCmd.execute() requires at least one of: plan item instances to move, plan item definitions to activate, terminate, change to available, wait for repetition, or stop waiting for repetition. If the ChangePlanItemStateBuilder is completely empty, Flowable throws FlowableIllegalArgumentException since there is no state change to perform.","triggerScenarios":"Calling cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId).changeState() without calling any of movePlanItemInstanceIdTo(...), activatePlanItemDefinition(...), terminatePlanItemDefinition(...), changeToAvailableState(...), waitingForRepetition(...), or removeWaitingForRepetition(...).","commonSituations":"Building the change list conditionally (e.g. from user input) and all conditions being false; a typo'd builder call returning a new builder instance; dynamic generation producing an empty plan.","solutions":["Add at least one movePlanItemInstanceIdTo(...) or activatePlanItemDefinition(...) call before changeState().","Check builder.getActivatePlanItemDefinitions() etc. size client-side and skip the changeState call when empty.","Fix code paths that silently drop intended builder operations (e.g. swallowed exceptions during plan construction)."],"exampleFix":"// before\nChangePlanItemStateBuilder b = cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId);\nif (applyMove) { b = b.movePlanItemInstanceIdTo(id, \"stage2\"); }\nb.changeState(); // throws when applyMove == false\n\n// after\nif (applyMove) {\n    cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId)\n        .movePlanItemInstanceIdTo(id, \"stage2\").changeState();\n}","handlingStrategy":"validation","validationCode":"if (moves.isEmpty() && activations.isEmpty() && terminations.isEmpty()) { skipChangeState(); return; }","typeGuard":null,"tryCatchPattern":"try { builder.changeState(); } catch (FlowableIllegalArgumentException e) { /* empty or invalid change plan */ }","preventionTips":["Only call changeState() after at least one builder operation succeeded.","Guard dynamic plan generation with an emptiness check.","Unit-test the code path where no operations are selected."],"tags":["cmmn","plan-item","empty-input","java"],"backgroundTag":"empty-required-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}