{"record":{"id":"3bb652d5266b29a9","repo":"flowable/flowable-engine","slug":"can-only-trigger-a-plan-item-that-is-in-the-active-3bb652","errorCode":null,"errorMessage":"Can only trigger a plan item that is in the ACTIVE state","messagePattern":"Can only trigger a plan item that is in the ACTIVE state","errorType":"validation","errorClass":"FlowableIllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/TaskActivityBehavior.java","lineNumber":57,"sourceCode":"    public void execute(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity) {\n        if (!evaluateIsBlocking(planItemInstanceEntity)) {\n            CommandContextUtil.getAgenda(commandContext).planCompletePlanItemInstanceOperation(planItemInstanceEntity);\n        }\n    }\n\n    protected boolean evaluateIsBlocking(DelegatePlanItemInstance planItemInstance) {\n        boolean blocking = isBlocking;\n        if (StringUtils.isNotEmpty(isBlockingExpression)) {\n            Expression expression = CommandContextUtil.getExpressionManager().createExpression(isBlockingExpression);\n            blocking = (Boolean) expression.getValue(planItemInstance);\n        }\n        return blocking;\n    }\n\n    @Override\n    public void trigger(CommandContext commandContext, PlanItemInstanceEntity planItemInstance) {\n        if (!PlanItemInstanceState.ACTIVE.equals(planItemInstance.getState())) {\n            throw new FlowableIllegalStateException(\"Can only trigger a plan item that is in the ACTIVE state\");\n        }\n        CommandContextUtil.getAgenda(commandContext).planCompletePlanItemInstanceOperation(planItemInstance);\n    }\n\n}\n","sourceCodeStart":39,"sourceCodeEnd":63,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/TaskActivityBehavior.java#L39-L63","documentation":"The engine attempted to trigger (complete) a CMMN plan item whose state is not ACTIVE. Only active plan items can be completed via the agenda's complete operation. This is an engine state invariant enforced in TaskActivityBehavior.trigger.","triggerScenarios":"Calling trigger on a task plan item that is available, waiting, suspended, completed, or terminated instead of active; racing completion via TaskService/CaseService while the plan item is in another lifecycle state.","commonSituations":"Programmatic completion from a listener or external trigger firing twice; manually completing a blocking task already acted upon; case instance suspended and later triggered.","solutions":["Check planItemInstance state (or query the plan item instance runtime) before triggering and only trigger when state == ACTIVE","Guard against duplicate triggers (idempotency key, state re-check) in your calling code","Use CaseService plan item lifecycle operations appropriate to the actual state rather than forcing complete"],"exampleFix":"// before\ncmmnTaskService.triggerPlanItem(planItemInstance.getId());\n// after\nPlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(id).singleResult();\nif (PlanItemInstanceState.ACTIVE.equals(pii.getState())) {\n    cmmnTaskService.triggerPlanItem(id);\n}","handlingStrategy":"try-catch","validationCode":"const pii = cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(id).singleResult();\nif (!pii || pii.getState() !== 'active') throw new Error('plan item not ACTIVE');","typeGuard":"function isActive(pii) { return pii != null && pii.getState() === 'active'; }","tryCatchPattern":"try {\n  cmmnTaskService.triggerPlanItem(id);\n} catch (e) {\n  if (e instanceof FlowableIllegalStateException) { /* re-read state, skip or requeue */ }\n  else throw e;\n}","preventionTips":["Re-read the plan item state immediately before triggering","Make triggers idempotent to avoid double completion","Do not cache plan item state across long-running transactions"],"tags":["cmmn","state-machine","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"}