flowable/flowable-engine · error · FlowableException

lazy loading outside command context for

Error message

lazy loading outside command context for 

What it means

TaskEntityImpl.getSpecificVariable() lazily fetches a single variable instance, which requires an active Flowable CommandContext. Flowable throws FlowableException when the entity is accessed outside a command (e.g. in a non-managed thread or after the command context closed).

Source

Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/persistence/entity/TaskEntityImpl.java:448

    @Override
    public void setFormKey(String formKey) {
        this.formKey = formKey;
    }

    // Override from VariableScopeImpl

    @Override
    protected boolean isPropagateToHistoricVariable() {
        return true;
    }

    // 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 FlowableException("lazy loading outside command context for " + this);
        }

        return getVariableServiceConfiguration().getVariableService()
                .createInternalVariableInstanceQuery()
                .taskId(id)
                .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);
        }
        return getVariableServiceConfiguration().getVariableService()
                .createInternalVariableInstanceQuery()
                .taskId(id)

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Access variables via TaskService.getVariable(taskId, name) instead of the entity so Flowable opens a command context
  2. Wrap direct entity access in managementService.executeCommand(...)
  3. Re-fetch the entity inside the current command rather than caching it across commands

Example fix

// before
TaskEntity entity = (TaskEntity) task; // detached
entity.getVariable("score"); // lazy load -> throws
// after
Object score = taskService.getVariable(task.getId(), "score");
Defensive patterns

Strategy: try-catch

Validate before calling

if (Context.getCommandContext() == null) {
    // not inside a command: use the service API instead
    Object value = taskService.getVariable(taskId, variableName);
}

Type guard

boolean canLazyLoad() { return Context.getCommandContext() != null; }

Try / catch

try {
    Object value = taskEntity.getVariable(variableName);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("lazy loading outside command context")) {
        Object value = taskService.getVariable(taskEntity.getId(), variableName); // re-fetch via service
    } else throw e;
}

Prevention

When it happens

Trigger: Calling taskEntity.getVariable(name) (or similar accessors hitting getSpecificVariable) from application code without wrapping in managementService.executeCommand(...), or retaining/using the entity after the command context ended (e.g. in an async executor thread).

Common situations: Detached task entities used in servlet/REST threads outside the Flowable command interceptor chain; storing entities across async boundaries; custom code bypassing the taskService and accessing entities directly.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/26fa5d3883e8d08d. Report an issue: GitHub.