{"record":{"id":"5520e20ff5666d8b","repo":"flowable/flowable-engine","slug":"setting-transient-variable-is-not-supported-for-re","errorCode":null,"errorMessage":"Setting transient variable is not supported for read only delegate execution","messagePattern":"Setting transient 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":43,"sourceCode":"    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":25,"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#L25-L51","documentation":"ReadOnlyDelegatePlanItemInstance is a default-implementation wrapper handed to CMMN delegates that must not mutate case state. All mutating methods, including setTransientVariable, throw UnsupportedOperationException by design to signal that writes are illegal in this execution context.","triggerScenarios":"Calling planItemInstance.setTransientVariable(name, value) from inside a delegate (e.g. a TaskListener or PlanItemJavaDelegate) that received a read-only delegate plan item instance, typically in read-only listener contexts such as CMMN case lifecycle listeners.","commonSituations":"Reusing a variable-writing delegate written for normal delegates in a read-only listener; copying BPMN task code into a CMMN lifecycle listener; frameworks injecting read-only instances for audit/history listeners.","solutions":["Remove the setTransientVariable call when running in a read-only context","Detect read-only instances before writing and skip or buffer the write","Use a different extension point (e.g. a non-read-only delegate/listener) if the write is required","Pass required data via the delegate's input mappings/field injections instead of transient variables"],"exampleFix":"// before\npublic void notify(DelegatePlanItemInstance planItemInstance) {\n    planItemInstance.setTransientVariable(\"result\", compute());\n}\n// after\npublic void notify(DelegatePlanItemInstance planItemInstance) {\n    if (!(planItemInstance instanceof ReadOnlyDelegatePlanItemInstance)) {\n        planItemInstance.setTransientVariable(\"result\", compute());\n    }\n}","handlingStrategy":"type-guard","validationCode":"boolean canWrite = !(planItemInstance instanceof ReadOnlyDelegatePlanItemInstance);","typeGuard":"if (planItemInstance instanceof ReadOnlyDelegatePlanItemInstance readOnly) { /* read-only: skip writes */ }","tryCatchPattern":"try { planItemInstance.setTransientVariable(name, value); } catch (UnsupportedOperationException e) { log.warn(\"Read-only context, skipped transient variable {}\", name); }","preventionTips":["Never write variables from lifecycle/audit listeners that receive read-only delegates","Pass data into delegates via field injection or input mappings instead of transient variables","Unit-test delegates against read-only instances to surface illegal writes early"],"tags":["java","cmmn","read-only","unsupported-operation"],"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"}