{"record":{"id":"773739731bec2226","repo":"flowable/flowable-engine","slug":"can-only-enable-a-plan-item-instance-which-is-in-s","errorCode":null,"errorMessage":"Can only enable a plan item instance which is in state AVAILABLE or DISABLED","messagePattern":"Can only enable a plan item instance which is in state AVAILABLE or DISABLED","errorType":"exception","errorClass":"FlowableIllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/EnablePlanItemInstanceCmd.java","lineNumber":44,"sourceCode":" */\npublic class EnablePlanItemInstanceCmd extends AbstractNeedsPlanItemInstanceCmd {\n\n    public EnablePlanItemInstanceCmd(String planItemInstanceId) {\n        super(planItemInstanceId);\n    }\n\n    public EnablePlanItemInstanceCmd(String planItemInstanceId, Map<String, Object> variables,\n            Map<String, Object> formVariables, String formOutcome, FormInfo formInfo,\n            Map<String, Object> localVariables, Map<String, Object> transientVariables) {\n        \n        super(planItemInstanceId, variables, formVariables, formOutcome, formInfo, localVariables, transientVariables);\n    }\n\n    @Override\n    protected void internalExecute(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity) {\n        if (!PlanItemInstanceState.AVAILABLE.equals(planItemInstanceEntity.getState())\n                && !PlanItemInstanceState.DISABLED.equals(planItemInstanceEntity.getState())) {\n            throw new FlowableIllegalStateException(\"Can only enable a plan item instance which is in state AVAILABLE or DISABLED\");\n        }\n        CommandContextUtil.getAgenda(commandContext).planEnablePlanItemInstanceOperation(planItemInstanceEntity, null);\n    }\n    \n}\n","sourceCodeStart":26,"sourceCodeEnd":50,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/EnablePlanItemInstanceCmd.java#L26-L50","documentation":"FlowableIllegalStateException thrown by EnablePlanItemInstanceCmd.internalExecute when the plan item instance is neither in AVAILABLE nor DISABLED state. Only available (e.g. waiting human task) or disabled plan items can be enabled. This is a lifecycle state guard.","triggerScenarios":"Calling enablePlanItemInstance on a plan item that is active, completed, in progress, or already enabled.","commonSituations":"UI enable button pressed twice; concurrent state change by another user or async job; stale plan item id after the case advanced; scripted test enabling an item that auto-started.","solutions":["Check the plan item state via PlanItemInstanceQuery and only enable when state is AVAILABLE or DISABLED","Catch FlowableIllegalStateException and treat as idempotent no-op","Refresh UI/model state before allowing enable actions"],"exampleFix":"// before\nplanItemInstanceService.enablePlanItemInstance(planItemInstanceId);\n// after\nPlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery()\n        .planItemInstanceId(planItemInstanceId).singleResult();\nif (pii != null && (PlanItemInstanceState.AVAILABLE.equals(pii.getState())\n        || PlanItemInstanceState.DISABLED.equals(pii.getState()))) {\n    planItemInstanceService.enablePlanItemInstance(planItemInstanceId);\n}","handlingStrategy":"validation","validationCode":"PlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(id).singleResult(); boolean ok = pii != null && (PlanItemInstanceState.AVAILABLE.equals(pii.getState()) || PlanItemInstanceState.DISABLED.equals(pii.getState())); if (!ok) return;","typeGuard":"boolean canEnable = pii != null && (PlanItemInstanceState.AVAILABLE.equals(pii.getState()) || PlanItemInstanceState.DISABLED.equals(pii.getState()));","tryCatchPattern":"try { planItemInstanceService.enablePlanItemInstance(id); } catch (FlowableIllegalStateException e) { log.info(\"plan item {} cannot be enabled from current state\", id); }","preventionTips":["Check plan item state before enable/disable actions","Handle concurrency: re-query state if time has elapsed since the page load"],"tags":["cmmn","plan-item","state-transition","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}