flowable/flowable-engine · error · FlowableException
lazy loading outside command context for
Error message
lazy loading outside command context for
What it means
ExecutionEntityImpl.getSpecificVariables lazy-loads a subset of an execution's variables on demand. Lazy loading only works inside a Flowable command context, because it needs the command context to reach the VariableService and run a query. When the entity is accessed outside a command (e.g. from a detached thread, a listener thread, or after the command finished), Context.getCommandContext() returns null and Flowable throws this FlowableException instead of returning partial data.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityImpl.java:961
CommandContext commandContext = Context.getCommandContext();
if (commandContext == null) {
throw new FlowableException("lazy loading outside command context for " + this);
}
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
return processEngineConfiguration.getVariableServiceConfiguration().getVariableService()
.createInternalVariableInstanceQuery()
.executionId(id)
.withoutTaskId()
.name(variableName)
.singleResult();
}
@Override
protected List<VariableInstanceEntity> getSpecificVariables(Collection<String> variableNames) {
CommandContext commandContext = Context.getCommandContext();
if (commandContext == null) {
throw new FlowableException("lazy loading outside command context for " + this);
}
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
return processEngineConfiguration.getVariableServiceConfiguration().getVariableService()
.createInternalVariableInstanceQuery()
.executionId(id)
.withoutTaskId()
.names(variableNames)
.list();
}
// event subscription support //////////////////////////////////////////////
@Override
public List<EventSubscriptionEntity> getEventSubscriptions() {
ensureEventSubscriptionsInitialized();
return eventSubscriptions;
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Wrap the entity access in a command: managementService.executeCommand(new CommandCommandContext...) or run the logic inside a Flowable command/listener so a CommandContext is active.
- Load all needed variables while still inside the original command (e.g. in the JavaDelegate/TaskListener), pass values (not entities) to other threads.
- For Spring apps, use the flowable-spring integration (SpringProcessEngineConfiguration) which keeps a command context open for the transaction, or annotate with @Transactional plus Flowable's command context propagation.
- If async, re-fetch data via the public API (runtimeService.getVariables(executionId)) instead of touching the lazy entity.
Example fix
// before (async thread, entity passed from a command) List<VariableInstanceEntity> vars = execution.getVariables(); // after (inside the same command, or re-query via public API) Map<String, Object> vars = runtimeService.getVariables(execution.getId());
Defensive patterns
Strategy: validation
Validate before calling
if (Context.getCommandContext() == null) {
// lazy loading unavailable: re-fetch via public API instead
Map<String, Object> vars =
runtimeService.getVariables(execution.getId());
} Type guard
boolean isInsideCommand() {
return Context.getCommandContext() != null;
} Try / catch
try {
vars = execution.getVariables();
} catch (FlowableException e) {
if (e.getMessage().startsWith("lazy loading outside command context")) {
vars = runtimeService.getVariables(execution.getId());
} else { throw e; }
} Prevention
- Only touch entity lazy collections inside commands, delegates, or listeners.
- Pass plain values (ids, copied maps) across thread boundaries, never entities.
- In async code, re-query via runtimeService/taskService public API.
When it happens
Trigger: Calling getVariables()/getVariable() on an ExecutionEntity (or TaskEntity, etc.) obtained from an async executor thread, a spring @Async method, a scheduled job, or a listener outside the command interceptor chain; holding a reference to an entity after CommandContext close and touching its variable collection later.
Common situations: Custom JobExecutors or thread pools using entities across threads; Spring integration where entity access happens outside a Flowable command (missing flowable spring command wrapper); unit tests constructing/inspecting entities directly without running a command.
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
- lazy loading outside command context for " + this
- lazy loading outside command context for
- lazy loading outside command context for
- Cannot use this method of the BusinessProcess bean within an
- Cannot use startProcessByName in an active command.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2504fdedcb81fdcf.
Report an issue: GitHub.