{"record":{"id":"925c80564fa522c5","repo":"flowable/flowable-engine","slug":"lazy-loading-outside-command-context","errorCode":null,"errorMessage":"lazy loading outside command context","messagePattern":"lazy loading outside command context","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TaskEntity.java","lineNumber":796,"sourceCode":"                    }\n                }\n            }\n        }\n    }\n\n    @Override\n    protected boolean isActivityIdUsedForDetails() {\n        return false;\n    }\n\n    // Override from VariableScopeImpl\n\n    // Overridden to avoid fetching *all* variables (as is the case in the super call)\n    @Override\n    protected VariableInstanceEntity getSpecificVariable(String variableName) {\n        CommandContext commandContext = Context.getCommandContext();\n        if (commandContext == null) {\n            throw new ActivitiException(\"lazy loading outside command context\");\n        }\n        VariableInstanceEntity variableInstance = commandContext\n                .getVariableInstanceEntityManager()\n                .findVariableInstanceByTaskAndName(id, variableName);\n\n        return variableInstance;\n    }\n\n    @Override\n    protected List<VariableInstanceEntity> getSpecificVariables(Collection<String> variableNames) {\n        CommandContext commandContext = Context.getCommandContext();\n        if (commandContext == null) {\n            throw new ActivitiException(\"lazy loading outside command context\");\n        }\n        return commandContext\n                .getVariableInstanceEntityManager()\n                .findVariableInstancesByTaskAndNames(id, variableNames);\n    }","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TaskEntity.java#L778-L814","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nTaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(id).singleResult();\nexecutor.submit(() -> task.getVariable(\"x\")); // throws outside command context\n// after\nexecutor.submit(() ->\n    processEngine.getManagementService().executeCommand(ctx ->\n        ctx.getTaskEntityManager().findById(id).getVariable(\"x\"))\n);","handlingStrategy":"type-guard","validationCode":"boolean safe = org.activiti.engine.impl.context.Context.getCommandContext() != null;","typeGuard":"boolean inCommandContext() {\n    return org.activiti.engine.impl.context.Context.getCommandContext() != null;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["lazy-loading","command-context","variables","lifecycle"],"backgroundTag":"lazy-loading-outside-command-context","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}