flowable/flowable-engine · error · org.activiti.engine.ActivitiIllegalArgumentException

variableScope cannot be null

Error message

variableScope cannot be null

What it means

The VariableScopeResolver constructor requires a non-null VariableScope; it exposes script variables of an execution or task to a script engine. Passing null makes the resolver meaningless, so it immediately throws ActivitiIllegalArgumentException.

Solutions

  1. Ensure the execution/task entity is fetched and non-null before creating the resolver.
  2. Assert the VariableScope argument before invoking the scripting API.
  3. If the entity may legitimately be absent, guard the call site rather than passing null.

Example fix

// before
new VariableScopeResolver(scopeMaybeNull);
// after
if (scopeMaybeNull == null) throw new IllegalArgumentException("no active execution/task scope for scripting");
new VariableScopeResolver(scopeMaybeNull);
Defensive patterns

Strategy: type-guard

Validate before calling

if (scope == null) throw new IllegalArgumentException("VariableScope required for script evaluation");

Type guard

boolean hasScope(VariableScope s) { return s instanceof ExecutionEntity || s instanceof TaskEntity; }

Try / catch

try {
    new VariableScopeResolver(scope);
} catch (ActivitiIllegalArgumentException e) {
    if (e.getMessage().contains("variableScope cannot be null")) { /* handle missing scope */ }
}

Prevention

When it happens

Trigger: Constructing new VariableScopeResolver(null) directly, or calling the script engine evaluation path (e.g. scriptingEngines.evaluateScript(..., null, ...)) with a null variable scope.

Common situations: Custom scripting integrations that pass a scope retrieved from a deleted/completed execution or task; null-returning custom scope lookups; unit tests exercising script evaluation without a real scope.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/scripting/VariableScopeResolver.java:35

import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.runtime.ExecutionImpl;
import org.flowable.variable.api.delegate.VariableScope;

/**
 * Bindings implementation using an {@link ExecutionImpl} as 'back-end'.
 * 
 * @author Tom Baeyens
 * @author Joram Barrez
 */
public class VariableScopeResolver implements Resolver {

    protected VariableScope variableScope;
    protected String variableScopeKey = "execution";

    public VariableScopeResolver(VariableScope variableScope) {
        if (variableScope == null) {
            throw new ActivitiIllegalArgumentException("variableScope cannot be null");
        }
        if (variableScope instanceof ExecutionEntity) {
            variableScopeKey = "execution";
        } else if (variableScope instanceof TaskEntity) {
            variableScopeKey = "task";
        } else {
            throw new ActivitiException("unsupported variable scope type: " + variableScope.getClass().getName());
        }
        this.variableScope = variableScope;
    }

    @Override
    public boolean containsKey(Object key) {
        return variableScopeKey.equals(key) || variableScope.hasVariable((String) key);
    }

    @Override
    public Object get(Object key) {

View on GitHub (pinned to d6d39ce1c6)