Activiti/Activiti · error · ActivitiException
lazy loading outside command context
Error message
lazy loading outside command context
What it means
VariableScopeImpl.ensureVariableInstancesInitialized() lazy-loads all variable instances from the database, which requires an active command context. Outside a command (detached scope object, wrong thread) the load is impossible and this ActivitiException is thrown.
Solutions
- Access variables within the same command/delegate execution where the scope is live
- Wrap access in managementService.executeCommand(...) to establish a command context
- Copy needed variable values out during the command instead of keeping entity references
Example fix
// before
execution.getVariables(); // after command ended -> throws
// after
managementService.executeCommand(context ->
context.getExecutionEntityManager().findById(executionId).getVariables()); Defensive patterns
Strategy: try-catch
Validate before calling
if (Context.getCommandContext() == null) {
Map<String,Object> vars = runtimeService.getVariables(executionId);
} Type guard
boolean scopeIsLive() {
return Context.getCommandContext() != null;
} Try / catch
try {
vars = variableScope.getVariables();
} catch (ActivitiException e) {
if (e.getMessage().contains("lazy loading")) {
vars = runtimeService.getVariables(executionId);
} else throw e;
} Prevention
- Read variables inside the delegate/command that owns the scope
- Fall back to runtimeService/taskService APIs outside commands
- Do not cache VariableScope/ExecutionEntity references
- Use executeCommand for custom engine access
When it happens
Trigger: Accessing any variable API (getVariables, hasVariables, getVariable, etc.) on an ExecutionEntity/TaskEntity/VariableScope when Context.getCommandContext() is null — e.g. after the command finished, in another thread, or on a cached entity.
Common situations: Holding DelegateExecution/TaskEntity references after delegate completion; reading variables in async code without a command; using entities cached from a previous service call.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- lazy loading outside command context
- lazy loading outside command context
- variable ' ' already exists. Use setVariableLocal if you…
- Can't start process ' ' as variables fail type validation
- Cannot set JPA variable
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/b1cfd98ce9027c0a.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/VariableScopeImpl.java:65
protected Map<String, VariableInstanceEntity> usedVariablesCache = new HashMap<String, VariableInstanceEntity>();
protected Map<String, VariableInstance> transientVariabes;
protected ELContext cachedElContext;
protected abstract Collection<VariableInstanceEntity> loadVariableInstances();
protected abstract VariableScopeImpl getParentVariableScope();
protected abstract void initializeVariableInstanceBackPointer(VariableInstanceEntity variableInstance);
protected void ensureVariableInstancesInitialized() {
if (variableInstances == null) {
variableInstances = new HashMap<String, VariableInstanceEntity>();
CommandContext commandContext = Context.getCommandContext();
if (commandContext == null) {
throw new ActivitiException("lazy loading outside command context");
}
Collection<VariableInstanceEntity> variableInstancesList = loadVariableInstances();
for (VariableInstanceEntity variableInstance : variableInstancesList) {
variableInstances.put(variableInstance.getName(), variableInstance);
}
}
}
public Map<String, Object> getVariables() {
return collectVariables(new HashMap<String, Object>());
}
public Map<String, VariableInstance> getVariableInstances() {
return collectVariableInstances(new HashMap<String, VariableInstance>());
}
public Map<String, Object> getVariables(Collection<String> variableNames) {
return getVariables(variableNames, true);View on GitHub (pinned to 56435b1a97)