{"record":{"id":"8e7b5558836228fb","repo":"flowable/flowable-engine","slug":"setting-variable-is-not-supported-for-read-only-de","errorCode":null,"errorMessage":"Setting variable is not supported for read only delegate execution","messagePattern":"Setting variable is not supported for read only delegate execution","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/delegate/ReadOnlyDelegatePlanItemInstance.java","lineNumber":38,"sourceCode":"/**\n * @author Filip Hrisafov\n */\npublic interface ReadOnlyDelegatePlanItemInstance extends PlanItemInstance, VariableContainer {\n\n    PlanItem getPlanItem();\n\n    default PlanItemDefinition getPlanItemDefinition() {\n        PlanItem planItem = getPlanItem();\n        if (planItem != null) {\n            return planItem.getPlanItemDefinition();\n        }\n\n        return null;\n    }\n\n    @Override\n    default void setVariable(String variableName, Object variableValue) {\n        throw new UnsupportedOperationException(\"Setting variable is not supported for read only delegate execution\");\n    }\n\n    @Override\n    default void setTransientVariable(String variableName, Object variableValue) {\n        throw new UnsupportedOperationException(\"Setting transient variable is not supported for read only delegate execution\");\n    }\n\n    @Override\n    default void setLocalizedName(String localizedName) {\n        throw new UnsupportedOperationException(\"Setting localized name is not supported for read only delegate execution\");\n    }\n}\n","sourceCodeStart":20,"sourceCodeEnd":51,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/delegate/ReadOnlyDelegatePlanItemInstance.java#L20-L51","documentation":"ReadOnlyDelegatePlanItemInstance.setVariable throws UnsupportedOperationException by default: this plan-item-instance view is read-only and forbids variable mutation. The engine hands listeners/delegates a read-only facade when writes are not permitted (e.g. read-only evaluation contexts in CMMN), so variable writes must go through a writable execution instead.","triggerScenarios":"Calling setVariable(...) (or setTransientVariable) on a ReadOnlyDelegatePlanItemInstance passed into a CMMN plan-item listener/ delegate where the engine supplies a read-only delegate.","commonSituations":"Writing variables from a CMMN TaskListener/ PlanItemLifecycleListener that receives a read-only plan item instance; code shared between process (BPMN) and case (CMMN) listeners assuming mutable execution; version changes where listeners became read-only.","solutions":["Write variables through engine services instead: cmmnRuntimeService.setVariable(caseInstanceId, name, value).","Obtain a writable DelegatePlanItemInstance/ plan item instance from the runtime service and set variables there.","Restructure the listener so variable changes happen in a phase/context where a mutable delegate is provided.","Split shared code paths: for read-only contexts, read variables; perform writes only with an explicit id via the runtime service."],"exampleFix":"// before\nreadOnlyPlanItemInstance.setVariable(\"status\", \"done\"); // throws\n// after\ncmmnRuntimeService.setVariable(planItemInstance.getCaseInstanceId(), \"status\", \"done\");","handlingStrategy":"try-catch","validationCode":"if (planItemInstance instanceof org.flowable.cmmn.api.delegate.ReadOnlyDelegatePlanItemInstance) {\n    cmmnRuntimeService.setVariable(caseInstanceId, name, value);\n} else {\n    planItemInstance.setVariable(name, value);\n}","typeGuard":"boolean isReadOnlyDelegate(DelegatePlanItemInstance p) {\n    return p instanceof org.flowable.cmmn.api.delegate.ReadOnlyDelegatePlanItemInstance;\n}","tryCatchPattern":"try {\n    planItemInstance.setVariable(name, value);\n} catch (UnsupportedOperationException e) {\n    cmmnRuntimeService.setVariable(caseInstanceId, name, value); // writable path\n}","preventionTips":["In CMMN listeners, never assume the provided plan item instance is mutable.","Write case variables through CmmnRuntimeService with explicit caseInstanceId.","Separate read-only inspection code from variable-writing code paths.","Check the Flowable version/ listener contract: read-only delegates are handed to some callbacks by design."],"tags":["flowable","cmmn","read-only","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-14T11:17:12.474Z"}