{"record":{"id":"b265b438686e868f","repo":"flowable/flowable-engine","slug":"execution-executionid-does-not-have-a-variabl","errorCode":null,"errorMessage":"Execution '${executionId}' does not have a variable '${variableName}' in scope ${scope}","messagePattern":"Execution '(.+?)' does not have a variable '(.+?)' in scope (.+?)","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"warning","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionVariableResource.java","lineNumber":198,"sourceCode":"    @ApiOperation(value = \"Delete a variable for an execution\", tags = { \"Executions\" }, nickname = \"deletedExecutionVariable\", code = 204)\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates both the execution and variable were found and variable has been deleted.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested execution was not found or the execution does not have a variable with the given name in the requested scope. Status description contains additional information about the error.\")\n    })\n    @DeleteMapping(value = \"/runtime/executions/{executionId}/variables/{variableName}\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void deleteVariable(@ApiParam(name = \"executionId\") @PathVariable(\"executionId\") String executionId, @ApiParam(name = \"variableName\") @PathVariable(\"variableName\") String variableName,\n            @RequestParam(value = \"scope\", required = false) String scope) {\n\n        Execution execution = getExecutionFromRequestWithoutAccessCheck(executionId);\n        // Determine scope\n        RestVariableScope variableScope = RestVariableScope.LOCAL;\n        if (scope != null) {\n            variableScope = RestVariable.getScopeFromString(scope);\n        }\n\n        if (!hasVariableOnScope(execution, variableName, variableScope)) {\n            throw new FlowableObjectNotFoundException(\"Execution '\" + execution.getId() + \"' does not have a variable '\" + variableName + \"' in scope \" + variableScope.name().toLowerCase(),\n                    VariableInstance.class);\n        }\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteExecutionVariables(execution, Collections.singleton(variableName), variableScope);\n        }\n\n        if (variableScope == RestVariableScope.LOCAL) {\n            runtimeService.removeVariableLocal(execution.getId(), variableName);\n        } else {\n            // Safe to use parentId, as the hasVariableOnScope would have\n            // stopped a global-var update on a root-execution\n            runtimeService.removeVariable(execution.getParentId(), variableName);\n        }\n    }\n}\n","sourceCodeStart":180,"sourceCodeEnd":215,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionVariableResource.java#L180-L215","documentation":"FlowableObjectNotFoundException thrown by deleteVariable when the target execution does not have the requested variable in the requested scope (local by default, or global if scope=global). Flowable treats deleting a non-existent variable as a not-found condition and includes the execution id, variable name, and scope in the message. Nothing is deleted when this is thrown.","triggerScenarios":"DELETE /runtime/process-instances/{executionId}/variables/{variableName} (optionally ?scope=global|local) where the variable was never set, was already deleted, or exists only in the other scope (e.g. set globally but deleting with default local scope).","commonSituations":"Race conditions where a concurrent request or process end already removed the variable, deleting a child-execution local variable via the parent execution id, expecting variable inheritance from the process definition (variables are runtime-scoped, not inherited).","solutions":["Verify the variable exists with GET /runtime/process-instances/{id}/variables and check its scope","Pass ?scope=global if the variable was set on the process instance rather than the local execution","Check you are using the correct execution id (child executions may hold local variables)","Handle 404 gracefully and treat it as idempotent deletion in retry/idempotency logic","Catch FlowableObjectNotFoundException (HTTP 404) around the DELETE call"],"exampleFix":"// before\ndelete(`/runtime/process-instances/${id}/variables/total`)\n// after\nconst vars = await get(`/runtime/process-instances/${id}/variables`);\nif (vars.some(v => v.name === 'total')) {\n  await delete(`/runtime/process-instances/${id}/variables/total`);\n}","handlingStrategy":"try-catch","validationCode":"const vars = await fetch(`/runtime/process-instances/${executionId}/variables`).then(r => r.json());\nconst exists = vars.some(v => v.name === variableName && (scope ? v.scope === scope : true));\nif (!exists) return; // already absent; skip delete","typeGuard":"function variableInScope(v, name, scope) {\n  return v.name === name && (scope ? v.scope?.toLowerCase() === scope.toLowerCase() : v.scope === 'local');\n}","tryCatchPattern":"try { await deleteVariable(executionId, variableName, scope); } catch (e) { if (e.status === 404) { /* treat as already deleted */ return; } throw e; }","preventionTips":["GET the variable list and confirm name+scope before deleting","Remember default scope is local; pass scope=global for process-instance-level variables","Treat 404 as idempotent success in cleanup jobs","Check you are targeting the execution that actually owns the variable"],"tags":["rest","not-found","variables","flowable"],"backgroundTag":"entity-not-found","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"}