flowable/flowable-engine · error · org.activiti.engine.ActivitiException
unsupported variable scope type
Error message
unsupported variable scope type: ${variableScope.getClass().getName()} What it means
VariableScopeResolver only supports ExecutionEntity ('execution') and TaskEntity ('task') as variable scopes, mapping them to the script variable key it exposes. Any other VariableScope implementation is rejected with this ActivitiException naming the concrete class.
Solutions
- Pass the underlying ExecutionEntity or TaskEntity instead of a wrapper/custom implementation.
- Extend VariableScopeResolver to support the custom scope type (add an instanceof branch with its own variableScopeKey).
- Check imports: use org.activiti.engine.impl.persistence.entity.ExecutionEntity/TaskEntity, not a different module's types.
Example fix
// before new VariableScopeResolver(customScopeWrapper); // after VariableScope real = ((CustomScopeWrapper) scope).getInnerScope(); // must be ExecutionEntity or TaskEntity new VariableScopeResolver(real);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(scope instanceof ExecutionEntity) && !(scope instanceof TaskEntity)) {
throw new IllegalArgumentException("Unsupported scope type: " + scope.getClass().getName());
} Type guard
boolean isSupportedScope(VariableScope s) {
return s instanceof org.activiti.engine.impl.persistence.entity.ExecutionEntity
|| s instanceof org.activiti.engine.impl.persistence.entity.TaskEntity;
} Try / catch
try {
resolver = new VariableScopeResolver(scope);
} catch (ActivitiException e) {
if (e.getMessage().startsWith("unsupported variable scope type")) { /* unwrap the inner scope */ }
} Prevention
- Pass the raw ExecutionEntity/TaskEntity, never wrapper or custom VariableScope implementations
- Check imports for scope classes — don't mix flowable5/flowable6 types
- If a custom scope is required, extend VariableScopeResolver with a new instanceof branch
When it happens
Trigger: Passing a custom VariableScope implementation (or a wrapper scope from an extension or a different engine module) into new VariableScopeResolver(...) for script evaluation.
Common situations: Custom scope wrappers introduced by extensions; mixing flowable6 scope classes into the flowable5 scripting path; mock VariableScope test doubles used in unit tests.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Class or class name is missing
- condition script returns non-Boolean: () for
- condition script returns non-Boolean
- unsupported variable scope type:
- A script is required
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d067a3114cbe2f97.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/scripting/VariableScopeResolver.java:42
*
* @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) {
if (variableScopeKey.equals(key)) {
return variableScope;
}
return variableScope.getVariable((String) key);
}
}View on GitHub (pinned to d6d39ce1c6)