flowable/flowable-engine · error · FlowableException

Unsupported variableContainer for key '${CASE_INSTANCE_KEY}'

Error message

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

What it means

CmmnVariableScopeResolver.get resolves well-known scripting variable keys (e.g. 'caseInstance') against the current variableContainer. When the container type does not map to the requested key (e.g. asking for the case instance while the container is a plain Task that is not CMMN-scoped, or a VariableScope that is neither CaseInstanceEntity, PlanItemInstance nor a CMMN Task), it throws this FlowableException. It signals a mismatch between the scripted variable being requested and the context in which the script runs.

Source

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

                throw new FlowableException("The service '" + key + "' is not available in the current context. Please enable services in scripting.");
            }
        } else if (CASE_INSTANCE_KEY.equals(key)) {
            if (scopeContainer instanceof CaseInstance) {
                return scopeContainer;

            } else if (scopeContainer instanceof PlanItemInstance planItemInstance) {
                if (StringUtils.isNotEmpty(planItemInstance.getCaseInstanceId())) {
                    return CommandContextUtil.getCaseInstanceEntityManager().findById(planItemInstance.getCaseInstanceId());
                }

            } else if (scopeContainer instanceof Task task) {
                if (StringUtils.isNotEmpty(task.getScopeId()) && ScopeTypes.CMMN.equals(task.getScopeType())) {
                    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;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the script/expression requesting 'caseInstance' executes within a CMMN case context (scopeContainer is a CaseInstanceEntity or CMMN-scoped Task/PlanItemInstance)
  2. If the container is a Task, verify task.getScopeType() equals ScopeTypes.CMMN and scopeId is set before resolving
  3. Pass the correct VariableContainer type for the key being resolved, or resolve the case instance explicitly via CaseInstanceEntityManager.findById
  4. Log scopeContainer.getClass().getName() to identify which unsupported container type is being passed and adjust the call site

Example fix

// before
Object caseInstance = resolver.get(CASE_INSTANCE_KEY, someVariableScope);
// after
if (someVariableScope instanceof CaseInstanceEntity || (someVariableScope instanceof Task t && ScopeTypes.CMMN.equals(t.getScopeType()))) {
    Object caseInstance = resolver.get(CASE_INSTANCE_KEY, someVariableScope);
} else {
    throw new IllegalStateException("caseInstance not available in this context");
}
Defensive patterns

Strategy: validation

Validate before calling

boolean canResolveCaseInstance(Object container) {
    return container instanceof CaseInstanceEntity
        || container instanceof PlanItemInstance
        || (container instanceof org.flowable.task.api.Task t && ScopeTypes.CMMN.equals(t.getScopeType()));
}

Type guard

boolean isCmmnScoped(Task t) { return t != null && t.getScopeId() != null && ScopeTypes.CMMN.equals(t.getScopeType()); }

Try / catch

try { return resolver.get(CASE_INSTANCE_KEY, container); } catch (FlowableException e) { if (e.getMessage().contains("Unsupported variableContainer")) { log.warn("No case context for container {}", container); return null; } throw e; }

Prevention

When it happens

Trigger: Calling variableScopeResolver.get(CASE_INSTANCE_KEY, scopeContainer) (directly or via CMMN script/expression variable resolution) with a scopeContainer that is not a CaseInstanceEntity, PlanItemInstance, or a Task whose scopeType is CMMN; e.g. requesting caseInstance inside a script executed with a standalone TaskHelper/VariableScope not attached to a case.

Common situations: Custom script tasks or delegates in CMMN using the implicit 'caseInstance' variable outside a case context; mixing process (BPMN) tasks with CMMN variable resolvers; upgrading Flowable and changing how the resolver is invoked from custom code.

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/bb5983589f2a620e. Report an issue: GitHub.