{"record":{"id":"6cb7b0ea52f21df4","repo":"flowable/flowable-engine","slug":"execution-executionid-does-not-have-a-variabl-6cb7b0","errorCode":null,"errorMessage":"Execution '${executionId}' does not have a variable '${variableName}' in scope ${scope}","messagePattern":"Execution '(.+?)' does not have a variable '(.+?)' in scope (.+?)","errorType":"exception","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceVariableResource.java","lineNumber":194,"sourceCode":"    @ApiOperation(value = \"Delete a variable\", tags = { \"Process Instance Variables\" }, nickname = \"deleteProcessInstanceVariable\", code = 204)\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the variable was found and has been deleted. Response-body is intentionally empty.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested variable was not found.\")\n    })\n    @DeleteMapping(value = \"/runtime/process-instances/{processInstanceId}/variables/{variableName}\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void deleteVariable(@ApiParam(name = \"processInstanceId\") @PathVariable(\"processInstanceId\") String processInstanceId, @ApiParam(name = \"variableName\") @PathVariable(\"variableName\") String variableName,\n            @RequestParam(value = \"scope\", required = false) String scope) {\n\n        Execution execution = getExecutionFromRequestWithoutAccessCheck(processInstanceId);\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                    VariableInstanceEntity.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    @Override\n    protected RestVariable constructRestVariable(String variableName, Object value, RestVariableScope variableScope, String executionId, boolean includeBinary) {","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceVariableResource.java#L176-L212","documentation":"DELETE on a process-instance variable checks hasVariableOnScope for the execution and the requested scope (local by default, or 'global'/'shared'). If the execution does not have that variable in that scope, Flowable throws FlowableObjectNotFoundException naming the execution, variable, and scope.","triggerScenarios":"DELETE /runtime/process-instances/{id}/variables/{variableName} (optionally ?scope=local|global) where the variable was never set, was already deleted, exists only in the other scope (e.g. variable is global but default scope=local is queried), or the execution id is wrong.","commonSituations":"Deleting a variable inherited from the process instance while omitting scope=global, double-delete retries, typos in variable names, variables set on a parent execution rather than the addressed one.","solutions":["Fetch GET /runtime/process-instances/{id}/variables first and confirm the variable name and its scope.","Add the correct scope query parameter, e.g. ?scope=global, when the variable is on the process instance rather than local.","Check for typos or case differences in variableName.","Make deletion idempotent in client code: treat 404 as already-deleted and skip."],"exampleFix":"// before\ncurl -X DELETE .../process-instances/123/variables/orderId  // variable is global\n\n// after\ncurl -X DELETE .../process-instances/123/variables/orderId?scope=global","handlingStrategy":"try-catch","validationCode":"const vars = await api.get(`/process-instances/${id}/variables`);\nconst v = vars.data.find(v => v.name === variableName);\nif (!v) throw new Error(`Variable ${variableName} not present; nothing to delete`);\nconst scopeParam = v.scope === 'global' ? '?scope=global' : '';","typeGuard":"function hasVariable(vars, name) { return Array.isArray(vars) && vars.some(v => v.name === name); }","tryCatchPattern":"try {\n  await api.delete(`/process-instances/${id}/variables/${name}${scopeParam}`);\n} catch (e) {\n  if (e.response?.status === 404) { /* already gone; treat as idempotent success */ }\n  else throw e;\n}","preventionTips":["List variables (with scope) before deleting.","Remember the default scope is local; pass ?scope=global for process-instance-level variables.","Make deletes idempotent by swallowing 404s."],"tags":["rest-api","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"}