Activiti/Activiti · error · ActivitiException
unsupported variable scope type
Error message
unsupported variable scope type: ${className} What it means
VariableScopeResolver only knows how to expose ExecutionEntity (bound as 'execution') and TaskEntity (bound as 'task') scopes; any other VariableScope implementation triggers this ActivitiException naming the class. This enforces that scripts can only resolve variables from supported scope objects. Custom VariableScope implementations must be handled by extending the resolver or converting to a supported scope first.
Solutions
- Pass the actual ExecutionEntity or TaskEntity associated with the script evaluation instead of a custom wrapper.
- Extend or subclass the resolver (or provide a custom ScriptBindingManager) to support your VariableScope type.
- In tests, use a real ExecutionEntity/TaskEntity (e.g. from the engine's test fixtures) rather than a mock VariableScope.
- Unwrap your custom scope to the underlying execution before creating script bindings.
Example fix
// before resolver = new VariableScopeResolver(config, myCustomScope); // after resolver = new VariableScopeResolver(config, (ExecutionEntity) myCustomScope.getExecution());
Defensive patterns
Strategy: validation
Validate before calling
if (!(variableScope instanceof ExecutionEntity) && !(variableScope instanceof TaskEntity)) {
throw new IllegalArgumentException(
"Unsupported scope for script bindings: " + variableScope.getClass().getName());
} Type guard
boolean isSupportedScope(VariableScope scope) {
return scope instanceof ExecutionEntity || scope instanceof TaskEntity;
} Try / catch
try {
new VariableScopeResolver(config, variableScope);
} catch (ActivitiException e) {
if (e.getMessage().startsWith("unsupported variable scope type")) {
logger.error("Convert {} to ExecutionEntity/TaskEntity before creating bindings",
variableScope.getClass().getName(), e);
}
} Prevention
- Only pass engine-managed ExecutionEntity or TaskEntity objects into scripting APIs.
- Avoid mock VariableScope fakes in tests; use engine test fixtures with real entities.
- If you need custom scopes, plan for a custom resolver/binding extension instead of forcing them through VariableScopeResolver.
When it happens
Trigger: Creating VariableScopeResolver with a VariableScope instance that is neither ExecutionEntity nor TaskEntity — e.g. a custom VariableScope implementation, a CaseExecution-like scope, or a test fake implementing VariableScope.
Common situations: Unit tests passing mock/fake VariableScope objects into scripting engines; custom scope classes added by embedders; using Activiti APIs with foreign scope wrappers; version upgrades where the resolver's supported types were narrowed.
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
- variableScope cannot be null
- Can't find scripting engine for
- condition script returns non-Boolean
- condition script returns null
- problem evaluating script
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/7ef20d353c3687f4.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/scripting/VariableScopeResolver.java:67
historyServiceKey,
formServiceKey
);
public VariableScopeResolver(
ProcessEngineConfigurationImpl processEngineConfiguration,
VariableScope variableScope
) {
this.processEngineConfiguration = processEngineConfiguration;
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;
}
public boolean containsKey(Object key) {
return variableScopeKey.equals(key) || KEYS.contains(key) || variableScope.hasVariable((String) key);
}
public Object get(Object key) {
if (variableScopeKey.equals(key)) {
return variableScope;
} else if (processEngineConfigurationKey.equals(key)) {
return processEngineConfiguration;
} else if (runtimeServiceKey.equals(key)) {
return processEngineConfiguration.getRuntimeService();
} else if (taskServiceKey.equals(key)) {
return processEngineConfiguration.getTaskService();
} else if (repositoryServiceKey.equals(key)) {View on GitHub (pinned to 56435b1a97)