flowable/flowable-engine · error · FlowableIllegalStateException

The case instance

Error message

The case instance 

What it means

Thrown as FlowableIllegalStateException when the case being reactivated has a reactivate event listener with an available condition expression, and evaluating that expression against the new runtime case instance did not return Boolean.TRUE. The engine only allows reactivation through a listener whose availability condition currently holds.

Solutions

  1. Set the case/plan-item variables the available condition depends on (e.g. via reactivationBuilder.variable(...)) before reactivating so the expression evaluates to true
  2. Fix or relax the availableCondition expression in the CMMN XML on the reactivation event listener
  3. Use a different reactivation plan item whose condition is met, or remove the condition if unconditional reactivation is intended

Example fix

// before
runtimeService.createCaseInstanceReactivationBuilder()
    .caseInstanceId(caseId)
    .reactivate();
// after
runtimeService.createCaseInstanceReactivationBuilder()
    .caseInstanceId(caseId)
    .variable("reactivationAllowed", true) // satisfies the listener's available condition
    .reactivate();
Defensive patterns

Strategy: validation

Validate before calling

// set variables the listener's available condition depends on before reactivation
builder.variable("reactivationAllowed", true);

Try / catch

try { builder.reactivate(); }
catch (FlowableIllegalStateException e) { log.warn("available condition false for {}", caseId); }

Prevention

When it happens

Trigger: Calling reactivateCaseInstance on a case whose CMMN model defines a reactivation (event) listener with an availableCondition that evaluates to false/null, e.g. because the referenced variables do not exist in the reactivated case context.

Common situations: Model changed after the original run so the condition now references variables that are not set; expression typo making it evaluate to null; reactivation attempted at a point in time when business data no longer satisfies the condition.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/66bfbdcc8087971e. Report an issue: GitHub.

Appendix: source

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

        }

        // set transient case variables, if the builder contains any
        if (reactivationBuilder.hasTransientVariables()) {
            caseInstanceEntity.setTransientVariables(reactivationBuilder.getTransientVariables());
        }

        // if there is an available condition on the reactivation event listener, evaluate it to make sure the listener is available for reactivation
        Case caze = CaseDefinitionUtil.getCase(instance.getCaseDefinitionId());
        ReactivateEventListener reactivateEventListener = caze.getReactivateEventListener();
        String availableConditionExpression = reactivateEventListener.getReactivationAvailableConditionExpression();
        if (StringUtils.isNotEmpty(availableConditionExpression)) {
            Object listenerAvailable = CommandContextUtil.getCmmnEngineConfiguration()
                .getExpressionManager()
                .createExpression(availableConditionExpression)
                .getValue(caseInstanceEntity);

            if (!Boolean.TRUE.equals(listenerAvailable)) {
                throw new FlowableIllegalStateException("The case instance " + caseInstanceEntity.getId()
                    + " cannot be reactivated, as the available condition of its reactivate event listener did not evaluate to true.");
            }
        }
        
        if (StringUtils.isNotEmpty(instance.getCallbackId()) && ReferenceTypes.PLAN_ITEM_CHILD_CASE.equals(instance.getCallbackType())) {
            PlanItemInstanceEntityManager planItemInstanceEntityManager = cmmnEngineConfiguration.getPlanItemInstanceEntityManager();
            PlanItemInstance parentPlanItemInstance = planItemInstanceEntityManager.findById(instance.getCallbackId());
            if (parentPlanItemInstance != null) {
                Case parentCase = CaseDefinitionUtil.getCase(parentPlanItemInstance.getCaseDefinitionId());
                PlanItem planItem = parentCase.getPlanModel().findPlanItemForPlanItemDefinitionInPlanFragmentOrDownwards(parentPlanItemInstance.getPlanItemDefinitionId());
                PlanItemInstanceEntity toActivateParentPlanItemInstance = planItemInstanceEntityManager
                        .createPlanItemInstanceEntityBuilder()
                        .planItem(planItem)
                        .caseDefinitionId(parentPlanItemInstance.getCaseDefinitionId())
                        .caseInstanceId(parentPlanItemInstance.getCaseInstanceId())
                        .tenantId(parentPlanItemInstance.getTenantId())
                        .create();
                

View on GitHub (pinned to d6d39ce1c6)