flowable/flowable-engine · error · FlowableIllegalStateException

Cannot trigger process task plan item instance : no referenc

Error message

Cannot trigger process task plan item instance : no reference id set

What it means

When triggering a process task plan item, the engine expects a referenceId pointing at the child process instance it started. A null referenceId means the linkage between the plan item and its child process was never recorded, so Flowable throws FlowableIllegalStateException.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/ProcessTaskActivityBehavior.java:166

            }

        } else {
            processInstanceService.startProcessInstance(processDefinitionId, processInstanceId, planItemInstanceEntity.getStageInstanceId(),
                    planItemInstanceEntity.getTenantId(), inParametersMap, businessKey, variableFormVariables, variableFormInfo, variableFormOutcome);
        }

        if (!blocking) {
            CommandContextUtil.getAgenda(commandContext).planCompletePlanItemInstanceOperation(planItemInstanceEntity);
        }
    }

    @Override
    public void trigger(CommandContext commandContext, PlanItemInstanceEntity planItemInstance) {
        if (!PlanItemInstanceState.ACTIVE.equals(planItemInstance.getState())) {
            throw new FlowableIllegalStateException("Can only trigger a plan item that is in the ACTIVE state");
        }
        if (planItemInstance.getReferenceId() == null) {
            throw new FlowableIllegalStateException("Cannot trigger process task plan item instance : no reference id set");
        }
        if (!ReferenceTypes.PLAN_ITEM_CHILD_PROCESS.equals(planItemInstance.getReferenceType())) {
            throw new FlowableException("Cannot trigger process task plan item instance : reference type '"
                    + planItemInstance.getReferenceType() + "' not supported for " + planItemInstance);
        }

        // Need to be set before planning the complete operation
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        CaseInstanceEntity caseInstance = cmmnEngineConfiguration.getCaseInstanceEntityManager().findById(planItemInstance.getCaseInstanceId());
        handleOutParameters(planItemInstance, caseInstance, cmmnEngineConfiguration.getProcessInstanceService());

        // Triggering the plan item (as opposed to a regular complete) terminates the process instance
        CommandContextUtil.getAgenda(commandContext).planCompletePlanItemInstanceOperation(planItemInstance);
        deleteProcessInstance(commandContext, planItemInstance);
    }

    @Override
    public void onStateTransition(CommandContext commandContext, DelegatePlanItemInstance planItemInstance, String transition) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify you are triggering the correct plan item instance — query it and confirm referenceType is PLAN_ITEM_CHILD_PROCESS and referenceId is set
  2. Do not trigger process task plan items directly; let the child process completion drive the trigger, or use the correct API for manually completing enabled/human tasks
  3. If data corruption is suspected, inspect ACT_CMMN_RU_PLAN_ITEM_INST.REFERENCE_ID_ for the offending row and restore proper engine-driven execution (restart case if needed)
  4. Audit custom code paths that manipulate plan item state outside the engine API

Example fix

// before
runtimeService.completePlanItemInstance(processTaskPlanItemId); // wrong: no child process behind it
// after
PlanItemInstance pii = runtimeService.createPlanItemInstanceQuery().planItemInstanceId(processTaskPlanItemId).singleResult();
if (pii != null && pii.getReferenceId() != null) {
    runtimeService.completePlanItemInstance(processTaskPlanItemId);
}
Defensive patterns

Strategy: type-guard

Validate before calling

PlanItemInstance pii = runtimeService.createPlanItemInstanceQuery()
    .planItemInstanceId(id).singleResult();
boolean safe = pii != null && pii.getReferenceId() != null;

Type guard

function hasChildProcessRef(pii) { return pii.getReferenceId() != null && 'planItemChildProcess'.equalsIgnoreCase(pii.getReferenceType()); }

Try / catch

try {
    // trigger path
} catch (FlowableIllegalStateException e) {
    if (e.getMessage().contains("no reference id set")) {
        // wrong plan item or broken linkage; inspect ACT_CMMN_RU_PLAN_ITEM_INST
    }
}

Prevention

When it happens

Trigger: trigger() called on an ACTIVE process-task plan item whose referenceId column is null — e.g. the plan item never actually started a child process (startup failed silently or state manipulated manually), or a non-process task handler routes to this behavior.

Common situations: Triggering the wrong plan item by id (a plan item that is not backed by a child process); data corruption or manual DB edits clearing REFERENCE_ID_; custom code that completes plan items without the engine having started the child process.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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