{"record":{"id":"4756698fc639a458","repo":"flowable/flowable-engine","slug":"empty-object-no-variables-can-be-set","errorCode":null,"errorMessage":"Empty object, no variables can be set","messagePattern":"Empty object, no variables can be set","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common-api/src/main/java/org/flowable/common/engine/api/variable/EmptyVariableContainer.java","lineNumber":37,"sourceCode":" * @author Arthur Hupka-Merle\n */\nclass EmptyVariableContainer implements VariableContainer {\n\n    static final EmptyVariableContainer INSTANCE = new EmptyVariableContainer();\n\n    @Override\n    public boolean hasVariable(String variableName) {\n        return false;\n    }\n\n    @Override\n    public Object getVariable(String variableName) {\n        return null;\n    }\n\n    @Override\n    public void setVariable(String variableName, Object variableValue) {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be set\");\n    }\n\n    @Override\n    public void setTransientVariable(String variableName, Object variableValue) {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be set\");\n    }\n\n    @Override\n    public String getTenantId() {\n        return null;\n    }\n\n    @Override\n    public Set<String> getVariableNames() {\n        return Collections.emptySet();\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common-api/src/main/java/org/flowable/common/engine/api/variable/EmptyVariableContainer.java#L19-L55","documentation":"EmptyVariableContainer is a read-only, immutable variable scope that always returns null for getVariable; its setVariable/setTransientVariable deliberately throw UnsupportedOperationException(\"Empty object, no variables can be set\") because the container represents an empty scope and cannot store any variables.","triggerScenarios":"Calling setVariable(name, value) or setTransientVariable(name, value) on an EmptyVariableContainer instance — e.g. code obtained a variable scope that is the empty container and then attempts to write.","commonSituations":"Delegate/listener code writing variables to a scope resolved in a context with no variables (such as certain delegate-execution placeholders), or tests using EmptyVariableContainer and then attempting writes.","solutions":["Write variables to a real, mutable scope (DelegateExecution, DelegateTask, VariableScope from the execution context) instead of the empty container","Check whether the container is an EmptyVariableContainer (or check writability) before writing","If you only need reads, keep in mind getVariable always returns null — obtain actual variables from the execution instead"],"exampleFix":"// before\nVariableScope scope = resolveScope();\nscope.setVariable(\"approved\", true); // throws if EmptyVariableContainer\n// after\nVariableScope scope = resolveScope();\nif (scope instanceof EmptyVariableContainer) {\n    throw new IllegalStateException(\"Cannot write variables to empty scope\");\n}\nscope.setVariable(\"approved\", true);","handlingStrategy":"type-guard","validationCode":"// ensure the scope is writable before setting variables\nif (scope instanceof EmptyVariableContainer) {\n    throw new IllegalStateException(\"Scope is read-only (empty); cannot set variables\");\n}","typeGuard":"static boolean isWritableScope(VariableScope scope) {\n    return !(scope instanceof EmptyVariableContainer);\n}","tryCatchPattern":"try {\n    scope.setVariable(\"approved\", true);\n} catch (UnsupportedOperationException e) {\n    LOGGER.error(\"Attempted to write variables to an empty variable container\");\n    throw new IllegalStateException(\"Use a real DelegateExecution/Task scope for writes\", e);\n}","preventionTips":["Obtain variable scopes from DelegateExecution/DelegateTask, not from empty-container placeholders","Check writability before bulk variable writes in generic code","Remember EmptyVariableContainer.getVariable always returns null — reads need the real scope too","In tests, use a simple in-memory VariableScope implementation instead of EmptyVariableContainer when writes are needed"],"tags":["java","unsupported-operation","variables"],"backgroundTag":"unsupported-operation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}