flowable/flowable-engine · error · ActivitiException
lazy loading outside command context
Error message
lazy loading outside command context
What it means
TaskEntity.getSpecificVariable lazy-loads a single task variable through the current CommandContext. Variables are persistence entities that can only be fetched inside an engine command. If the entity is accessed outside a command (no active CommandContext), the engine cannot load the variable and throws this ActivitiException.
Source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TaskEntity.java:796
}
}
}
}
}
@Override
protected boolean isActivityIdUsedForDetails() {
return false;
}
// Override from VariableScopeImpl
// Overridden to avoid fetching *all* variables (as is the case in the super call)
@Override
protected VariableInstanceEntity getSpecificVariable(String variableName) {
CommandContext commandContext = Context.getCommandContext();
if (commandContext == null) {
throw new ActivitiException("lazy loading outside command context");
}
VariableInstanceEntity variableInstance = commandContext
.getVariableInstanceEntityManager()
.findVariableInstanceByTaskAndName(id, variableName);
return variableInstance;
}
@Override
protected List<VariableInstanceEntity> getSpecificVariables(Collection<String> variableNames) {
CommandContext commandContext = Context.getCommandContext();
if (commandContext == null) {
throw new ActivitiException("lazy loading outside command context");
}
return commandContext
.getVariableInstanceEntityManager()
.findVariableInstancesByTaskAndNames(id, variableNames);
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Read variables via TaskService.getVariable(taskId, name) inside your API call instead of on the entity directly
- Wrap custom code in managementService.executeCommand(new Command<...>() {...}) so a CommandContext exists
- Re-fetch a fresh task entity within the command rather than reusing a detached one
- For async work, pass taskId/values, not the entity
Example fix
// before
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(id).singleResult();
executor.submit(() -> task.getVariable("x")); // throws outside command context
// after
executor.submit(() ->
processEngine.getManagementService().executeCommand(ctx ->
ctx.getTaskEntityManager().findById(id).getVariable("x"))
); Defensive patterns
Strategy: type-guard
Validate before calling
boolean safe = org.activiti.engine.impl.context.Context.getCommandContext() != null;
Type guard
boolean inCommandContext() {
return org.activiti.engine.impl.context.Context.getCommandContext() != null;
} Prevention
- Never call entity-level getVariable directly; go through TaskService
- Wrap any custom entity access in managementService.executeCommand
- Do not cache TaskEntity instances across commands/requests
When it happens
Trigger: Accessing task variables (getVariable/getVariableNames on a TaskEntity or its variable scope) from outside a command: e.g. in a non-managed thread, after the engine command finished, in application code holding a detached TaskEntity, or in custom code invoked without CommandContextInterceptor.
Common situations: Caching TaskEntity objects across requests and reading variables later; using entities inside async threads/executor tasks without wrapping in managementService.executeCommand; deserialized entities used in tests without a command context.
Related errors
- lazy loading outside command context
- lazy loading outside command context for " + this
- Cannot work with cached variables in an active command.
- Cannot initialize byte array. There is no command context an
- lazy loading outside command context for
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/925c80564fa522c5.
Report an issue: GitHub.