{"record":{"id":"b1cfd98ce9027c0a","repo":"Activiti/Activiti","slug":"lazy-loading-outside-command-context-b1cfd9","errorCode":null,"errorMessage":"lazy loading outside command context","messagePattern":"lazy loading outside command context","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/VariableScopeImpl.java","lineNumber":65,"sourceCode":"    protected Map<String, VariableInstanceEntity> usedVariablesCache = new HashMap<String, VariableInstanceEntity>();\n\n    protected Map<String, VariableInstance> transientVariabes;\n\n    protected ELContext cachedElContext;\n\n    protected abstract Collection<VariableInstanceEntity> loadVariableInstances();\n\n    protected abstract VariableScopeImpl getParentVariableScope();\n\n    protected abstract void initializeVariableInstanceBackPointer(VariableInstanceEntity variableInstance);\n\n    protected void ensureVariableInstancesInitialized() {\n        if (variableInstances == null) {\n            variableInstances = new HashMap<String, VariableInstanceEntity>();\n\n            CommandContext commandContext = Context.getCommandContext();\n            if (commandContext == null) {\n                throw new ActivitiException(\"lazy loading outside command context\");\n            }\n            Collection<VariableInstanceEntity> variableInstancesList = loadVariableInstances();\n            for (VariableInstanceEntity variableInstance : variableInstancesList) {\n                variableInstances.put(variableInstance.getName(), variableInstance);\n            }\n        }\n    }\n\n    public Map<String, Object> getVariables() {\n        return collectVariables(new HashMap<String, Object>());\n    }\n\n    public Map<String, VariableInstance> getVariableInstances() {\n        return collectVariableInstances(new HashMap<String, VariableInstance>());\n    }\n\n    public Map<String, Object> getVariables(Collection<String> variableNames) {\n        return getVariables(variableNames, true);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/Activiti/Activiti/blob/56435b1a97deeafdc09dd40074b056c89fba5a8a/activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/VariableScopeImpl.java#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"Holding DelegateExecution/TaskEntity references after delegate completion; reading variables in async code without a command; using entities cached from a previous service call.","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"],"exampleFix":"// before\nexecution.getVariables(); // after command ended -> throws\n// after\nmanagementService.executeCommand(context ->\n    context.getExecutionEntityManager().findById(executionId).getVariables());","handlingStrategy":"try-catch","validationCode":"if (Context.getCommandContext() == null) {\n    Map<String,Object> vars = runtimeService.getVariables(executionId);\n}","typeGuard":"boolean scopeIsLive() {\n    return Context.getCommandContext() != null;\n}","tryCatchPattern":"try {\n    vars = variableScope.getVariables();\n} catch (ActivitiException e) {\n    if (e.getMessage().contains(\"lazy loading\")) {\n        vars = runtimeService.getVariables(executionId);\n    } else throw e;\n}","preventionTips":["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"],"tags":["lazy-loading","command-context","variables","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"56435b1a97deeafdc09dd40074b056c89fba5a8a","analyzedAt":"2026-09-09T21:00:06.703Z","contentChangedAt":"2026-09-09T21:00:06.703Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}