{"record":{"id":"41d481a4e47be24b","repo":"flowable/flowable-engine","slug":"empty-object-no-variables-can-be-removed","errorCode":null,"errorMessage":"Empty object, no variables can be removed","messagePattern":"Empty object, no variables can be removed","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"modules/flowable-variable-service-api/src/main/java/org/flowable/variable/api/delegate/EmptyVariableScope.java","lineNumber":210,"sourceCode":"        return false;\n    }\n\n    @Override\n    public boolean hasVariableLocal(String variableName) {\n        return false;\n    }\n\n    public void createVariableLocal(String variableName, Object value) {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be created\");\n    }\n\n    public void createVariablesLocal(Map<String, ? extends Object> variables) {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be created\");\n    }\n\n    @Override\n    public void removeVariable(String variableName) {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be removed\");\n    }\n\n    @Override\n    public void removeVariableLocal(String variableName) {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be removed\");\n    }\n\n    @Override\n    public void removeVariables() {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be removed\");\n    }\n\n    @Override\n    public void removeVariablesLocal() {\n        throw new UnsupportedOperationException(\"Empty object, no variables can be removed\");\n    }\n\n    @Override","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-variable-service-api/src/main/java/org/flowable/variable/api/delegate/EmptyVariableScope.java#L192-L228","documentation":"Deliberate unsupported-operation sentinel: EmptyVariableScope is an immutable placeholder scope, so removeVariable (like all mutators) is hard-wired to throw; it fires only if code mutates the shared empty scope.","triggerScenarios":"Calling removeVariable(name) on EmptyVariableScope, e.g. cleanup code removing variables on a scope that resolved to the empty sentinel.","commonSituations":"Cleanup logic in delegates/listeners deleting variables after the process instance ended; generic variable-management helpers calling removeVariable on whatever scope they were handed.","solutions":["Guard with instanceof EmptyVariableScope and skip the removal.","Fetch the live execution/task via runtimeService/taskService before removing.","Perform removals during the active delegate execution.","If nothing should remain, consider deleting the whole execution/instance instead of per-variable removal."],"exampleFix":"// before\nscope.removeVariable(\"tempData\");\n\n// after\nif (!(scope instanceof EmptyVariableScope)) {\n    scope.removeVariable(\"tempData\");\n}","handlingStrategy":"type-guard","validationCode":"if (scope instanceof EmptyVariableScope) {\n    throw new IllegalStateException(\"Cannot remove variables from empty scope\");\n}","typeGuard":"boolean isWritableScope(VariableScope scope) {\n    return scope != null && !(scope instanceof EmptyVariableScope);\n}","tryCatchPattern":"try {\n    scope.removeVariable(name);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Empty object\")) {\n        logger.warn(\"Removal skipped: empty scope\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Guard removal paths with an EmptyVariableScope check.","Remove variables via runtimeService/taskService with ids when the scope may be detached.","Do cleanup during the active execution, not after instance completion.","Treat EmptyVariableScope as read-only everywhere in your codebase."],"tags":["flowable","unsupported-operation","variable-scope","immutable"],"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"}