{"record":{"id":"74a8bbe28cd84dc3","repo":"flowable/flowable-engine","slug":"local-variable-name-is-already-present-on-pla","errorCode":null,"errorMessage":"Local variable '${name}' is already present on plan item instance '${instanceId}'.","messagePattern":"Local variable '(.+?)' is already present on plan item instance '(.+?)'\\.","errorType":"http","errorClass":"FlowableConflictException","httpStatus":409,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/BaseVariableResource.java","lineNumber":403,"sourceCode":"            throw new FlowableIllegalArgumentException(\"Could not process multipart content\", ioe);\n            \n        } catch (ClassNotFoundException ioe) {\n            throw new FlowableContentNotSupportedException(\n                    \"The provided body contains a serialized object for which the class was not found: \" + ioe.getMessage());\n        }\n    }\n\n    protected void setVariable(String instanceId, String name, Object value, RestVariableScope scope, boolean isNew, boolean async, VariableInterceptor variableInterceptor) {\n        if (isNew) {\n            variableInterceptor.createVariables(Collections.singletonMap(name, value));\n        } else {\n            variableInterceptor.updateVariables(Collections.singletonMap(name, value));\n        }\n\n        if (RestVariableScope.LOCAL == scope) {\n            //the guard is only added here, because this whole block is new\n            if (isNew && runtimeService.hasLocalVariable(instanceId, name)) {\n                throw new FlowableConflictException(\"Local variable '\" + name + \"' is already present on plan item instance '\" + instanceId + \"'.\");\n            }\n            \n            if (async) {\n                runtimeService.setLocalVariableAsync(instanceId, name, value);\n            } else {\n                runtimeService.setLocalVariable(instanceId, name, value);\n            }\n            \n        } else {\n            if (async) {\n                runtimeService.setVariableAsync(instanceId, name, value);\n            } else {\n                runtimeService.setVariable(instanceId, name, value);\n            }\n        }\n    }\n\n    protected VariableInterceptor createVariableInterceptor(PlanItemInstance planItemInstance) {","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/BaseVariableResource.java#L385-L421","documentation":"When creating a LOCAL variable via the CMMN REST API with the 'new variable' semantics (isNew) and async flag path, Flowable first checks runtimeService.hasLocalVariable; if a local variable with that name already exists on the plan item instance, it throws FlowableConflictException (HTTP 409) instead of silently overwriting. This protects callers from accidentally clobbering existing local variables.","triggerScenarios":"POSTing a new local variable to /cmmn-runtime/plan-item-instances/{id}/variables with scope=local for a variable name that already exists locally on that plan item instance, when isNew is true.","commonSituations":"Retry logic re-POSTing a variable that was already created in a previous attempt, concurrent clients creating the same variable name, scripts that assume variables are upserted when the create endpoint is actually create-only.","solutions":["Use PUT (update) on the existing variable instead of POST create if overwriting is intended","Check existence first via GET /cmmn-runtime/plan-item-instances/{id}/variables/{name} and choose POST or PUT accordingly","Use a different variable name, or remove the existing local variable before recreating","Treat HTTP 409 as 'already exists' in client retry logic and switch to update"],"exampleFix":"// before: always POST\npost(variablesUrl, newVariable(name, value, LOCAL));\n// after\nif (!exists(variablesUrl + \"/\" + name)) {\n    post(variablesUrl, newVariable(name, value, LOCAL));\n} else {\n    put(variablesUrl + \"/\" + name, newVariable(name, value, LOCAL));\n}","handlingStrategy":"validation","validationCode":"boolean exists = restTemplate.getForObject(\n    base + \"/cmmn-runtime/plan-item-instances/\" + planItemId + \"/variables/\" + name, Boolean.class) != null;\nif (exists) {\n    // update via PUT instead of POST create\n}","typeGuard":"null","tryCatchPattern":"try {\n    postLocalVariable(planItemId, name, value);\n} catch (HttpClientErrorException.Conflict e) {\n    putLocalVariable(planItemId, name, value); // fall back to update\n}","preventionTips":["Check variable existence before POSTing new local variables","Use PUT for idempotent updates instead of POST create","Handle HTTP 409 as 'already exists' in retry logic","Avoid concurrent creation of the same variable name from multiple clients"],"tags":["conflict","variable","cmmn","rest"],"backgroundTag":"resource-already-exists","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"}