flowable/flowable-engine · error · FlowableException

Unsupported variableContainer for key '${PLAN_ITEM_INSTANCE_

Error message

Unsupported variableContainer for key '${PLAN_ITEM_INSTANCE_KEY}': ${scopeContainer.class.name}

What it means

Same resolver as error 930 but for PLAN_ITEM_INSTANCE_KEY: when the script requests the 'planItemInstance' variable and the scopeContainer is not a PlanItemInstance nor a Task with subScopeId scoped to a CMMN plan item, the resolver throws this FlowableException. It means the plan-item context required by the script is unavailable in the given container.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/scripting/CmmnVariableScopeResolver.java:118

                    return CommandContextUtil.getCaseInstanceEntityManager().findById(task.getScopeId());
                }

            }

            throw new FlowableException("Unsupported variableContainer for key '" + CASE_INSTANCE_KEY + "': " + scopeContainer.getClass().getName());

        } else if (PLAN_ITEM_INSTANCE_KEY.equals(key)) {
            if (scopeContainer instanceof PlanItemInstance) {
                return scopeContainer;

            }  else if (scopeContainer instanceof Task task) {
                if (StringUtils.isNotEmpty(task.getSubScopeId()) && ScopeTypes.CMMN.equals(task.getScopeType())) {
                    return CommandContextUtil.getPlanItemInstanceEntityManager().findById(task.getSubScopeId());
                }

            }

            throw new FlowableException("Unsupported variableContainer for key '" + PLAN_ITEM_INSTANCE_KEY + "': " + scopeContainer.getClass().getName());

        } else if (TASK_KEY.equals(key)) {
            if (scopeContainer instanceof Task) {
                return scopeContainer;

            } else  if (scopeContainer instanceof PlanItemInstance planItemInstance) {
                return CommandContextUtil.getTaskService().findTasksBySubScopeIdScopeType(planItemInstance.getId(), ScopeTypes.CMMN);

            } else {
                throw new FlowableException("Unsupported variableContainer for key '" + TASK_KEY + "': " + scopeContainer.getClass().getName());

            }

        } else {
            return inputVariableContainer.getVariable((String) key);

        }
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Only reference 'planItemInstance' in scripts/expressions evaluated at plan-item level (plan item listeners, plan-item-scoped tasks)
  2. If the container is a Task, ensure getSubScopeId() is set and scopeType is CMMN so the resolver can look up the plan item
  3. Resolve the PlanItemInstance explicitly via PlanItemInstanceEntityManager.findById(subScopeId) when working outside the resolver
  4. Check the container type in the exception message and pass a PlanItemInstanceEntity instead

Example fix

// before
Object pii = resolver.get(PLAN_ITEM_INSTANCE_KEY, caseInstanceEntity);
// after
Object pii = (container instanceof PlanItemInstance) ? resolver.get(PLAN_ITEM_INSTANCE_KEY, container) : planItemInstanceEntityManager.findById(task.getSubScopeId());
Defensive patterns

Strategy: type-guard

Validate before calling

boolean canResolvePlanItem(Object container) {
    return container instanceof PlanItemInstance
        || (container instanceof org.flowable.task.api.Task t && t.getSubScopeId() != null && ScopeTypes.CMMN.equals(t.getScopeType()));
}

Type guard

boolean isPlanItemScoped(Task t) { return t != null && StringUtils.isNotEmpty(t.getSubScopeId()) && ScopeTypes.CMMN.equals(t.getScopeType()); }

Try / catch

try { return resolver.get(PLAN_ITEM_INSTANCE_KEY, container); } catch (FlowableException e) { if (e.getMessage().startsWith("Unsupported variableContainer")) return null; throw e; }

Prevention

When it happens

Trigger: Requesting 'planItemInstance' from a script whose variableContainer is a CaseInstanceEntity, a non-CMMN Task, or any other VariableScope type; calling resolver.get(PLAN_ITEM_INSTANCE_KEY, container) with a Task whose subScopeId is empty or whose scopeType is not CMMN.

Common situations: Scripts in case-level (not plan-item-level) listeners referencing planItemInstance; reusing a BPMN script context in CMMN; custom code resolving plan item variables from a case-wide scope.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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