{"record":{"id":"09e814f4980e7463","repo":"flowable/flowable-engine","slug":"can-only-disable-a-plan-item-instance-which-is-in","errorCode":null,"errorMessage":"Can only disable a plan item instance which is in state ENABLED","messagePattern":"Can only disable a plan item instance which is in state ENABLED","errorType":"exception","errorClass":"FlowableIllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DisablePlanItemInstanceCmd.java","lineNumber":45,"sourceCode":"public class DisablePlanItemInstanceCmd extends AbstractNeedsPlanItemInstanceCmd {\n\n    public DisablePlanItemInstanceCmd(String planItemInstanceId) {\n        super(planItemInstanceId);\n    }\n\n    public DisablePlanItemInstanceCmd(String planItemInstanceId, Map<String, Object> variables,\n            Map<String, Object> formVariables, String formOutcome, FormInfo formInfo,\n            Map<String, Object> localVariables,\n            Map<String, Object> transientVariables) {\n        \n        super(planItemInstanceId, variables, formVariables, formOutcome, formInfo, \n                localVariables, transientVariables);\n    }\n\n    @Override\n    protected void internalExecute(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity) {\n        if (!PlanItemInstanceState.ENABLED.equals(planItemInstanceEntity.getState())) {\n            throw new FlowableIllegalStateException(\"Can only disable a plan item instance which is in state ENABLED\");\n        }\n        CommandContextUtil.getAgenda(commandContext).planDisablePlanItemInstanceOperation(planItemInstanceEntity);\n    }\n    \n}\n","sourceCodeStart":27,"sourceCodeEnd":51,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DisablePlanItemInstanceCmd.java#L27-L51","documentation":"FlowableIllegalStateException thrown by DisablePlanItemInstanceCmd.internalExecute when the target plan item instance is not in the ENABLED state. Only enabled plan items (e.g. human task stage entries waiting for user action) can be disabled. This is a state-machine guard to prevent illegal lifecycle transitions.","triggerScenarios":"Calling planItemInstanceService.disablePlanItemInstance(id) on a plan item already disabled, completed, active, or unavailable.","commonSituations":"Double-clicking a 'disable' button in a task UI so the second call hits an already-DISABLED item; concurrent user actions; stale plan item id shown in UI after the state changed; scripting against a case whose plan item auto-completed.","solutions":["Query the plan item state first and only call disable when it equals PlanItemInstanceState.ENABLED","Catch FlowableIllegalStateException and treat it as a no-op or user-facing 'already handled' message","Refresh UI state after every state-changing call to avoid stale actions"],"exampleFix":"// before\nplanItemInstanceService.disablePlanItemInstance(planItemInstanceId);\n// after\nPlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery()\n        .planItemInstanceId(planItemInstanceId).singleResult();\nif (pii != null && PlanItemInstanceState.ENABLED.equals(pii.getState())) {\n    planItemInstanceService.disablePlanItemInstance(planItemInstanceId);\n}","handlingStrategy":"validation","validationCode":"PlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(id).singleResult(); if (pii == null || !PlanItemInstanceState.ENABLED.equals(pii.getState())) return;","typeGuard":"boolean canDisable = pii != null && PlanItemInstanceState.ENABLED.equals(pii.getState());","tryCatchPattern":"try { planItemInstanceService.disablePlanItemInstance(id); } catch (FlowableIllegalStateException e) { log.info(\"plan item {} not in ENABLED state\", id); }","preventionTips":["Disable UI actions based on live plan item state","Treat state-changing calls as non-idempotent and refresh state after each"],"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"}