flowable/flowable-engine · error · FlowableException

The service '${key}' is not available in the current context

Error message

The service '${key}' is not available in the current context. Please enable services in scripting.

What it means

CmmnVariableScopeResolver.get(Object key) throws FlowableException when a script/expression references a Flowable service (e.g. cmmnEngineConfiguration service names) while isServicesEnabledInScripting() is false. This is a deliberate guard: service access from scripts is opt-in for security reasons.

Source

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

        }
        this.scopeContainer = scopeContainer;
        this.inputVariableContainer = inputVariableContainer;
        this.engineConfiguration = engineConfiguration;
    }

    @Override
    public boolean containsKey(Object key) {
        return inputVariableContainer.hasVariable((String) key) || KEYS.contains(key)
                || SERVICE_RESOLVERS.containsKey(key) && engineConfiguration.isServicesEnabledInScripting();
    }

    @Override
    public Object get(Object key) {
        if (SERVICE_RESOLVERS.containsKey((String) key)) {
            if (engineConfiguration.isServicesEnabledInScripting()) {
                return SERVICE_RESOLVERS.get(key).apply(engineConfiguration);
            } else {
                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());

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Enable services in scripting: cmmnEngineConfiguration.setServicesEnabledInScripting(true).
  2. Rewrite the script to not use engine services — obtain needed data as variables before the script runs.
  3. Expose only required values via delegate expression fields or script bindings instead of service lookups (recommended for security).

Example fix

// before (config)
// services disabled by default; script uses cmmnRuntimeService
// after
cmmnEngineConfiguration.setServicesEnabledInScripting(true);
Defensive patterns

Strategy: fallback

Validate before calling

// before running scripts, check:
if (!engineConfig.isServicesEnabledInScripting()) { sanitizeScriptsToAvoidServiceLookups(); }

Try / catch

try { return resolver.get(key); } catch (FlowableException e) { log.warn("Service '{}' unavailable in scripting; returning null binding", key); return null; }

Prevention

When it happens

Trigger: A script (Groovy/JS) in a CMMN case references a service resolver key (e.g. 'cmmnRuntimeService' style lookups on the resolver) while cmmnEngineConfiguration.setServicesEnabledInScripting(false) (the default).

Common situations: Migrating scripts from older Flowable versions where services were enabled by default; deploying a case with scripts that use service beans into an environment hardened with services disabled.

Related errors


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