flowable/flowable-engine · error · FlowableObjectNotFoundException
Plan item instance '${id}' does not have a variable '${varia
Error message
Plan item instance '${id}' does not have a variable '${variableName}' in local scope What it means
deleteVariable checks runtimeService.hasLocalVariable(planItem.getId(), variableName); when the plan item instance has no such variable in LOCAL scope it throws FlowableObjectNotFoundException with VariableInstance.class. Only local scope is consulted here — an instance-scope (case) variable with the same name will not satisfy this check.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/PlanItemInstanceVariableResource.java:178
setSimpleVariable(restVariable, planItem.getId(), false, true, RestVariable.RestVariableScope.LOCAL, CmmnRestResponseFactory.VARIABLE_PLAN_ITEM, createVariableInterceptor(planItem));
}
}
@ApiOperation(value = "Delete a variable for a plan item instance", tags = { "Plan Item Instances" }, nickname = "deletePlanItemVariable", code = 204)
@ApiResponses(value = {
@ApiResponse(code = 204, message = "Indicates both the plan item and variable were found and variable has been deleted."),
@ApiResponse(code = 404, message = "Indicates the requested plan item was not found or the plan item does not have a variable with the given name in the requested scope. Status description contains additional information about the error.")
})
@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping(value = "/cmmn-runtime/plan-item-instances/{planItemInstanceId}/variables/{variableName}")
public void deleteVariable(@ApiParam(name = "planItemInstanceId") @PathVariable("planItemInstanceId") String planItemInstanceId,
@ApiParam(name = "variableName") @PathVariable("variableName") String variableName,
@RequestParam(value = "scope", required = false) String scope) {
PlanItemInstance planItem = getPlanItemInstanceFromRequest(planItemInstanceId);
if (!runtimeService.hasLocalVariable(planItem.getId(), variableName)) {
throw new FlowableObjectNotFoundException(
"Plan item instance '" + planItem.getId() + "' does not have a variable '" + variableName + "' in local scope",
VariableInstance.class);
}
if (restApiInterceptor != null) {
restApiInterceptor.deletePlanItemInstanceVariables(planItem, Collections.singleton(variableName));
}
runtimeService.removeLocalVariable(planItem.getId(), variableName);
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check the variable exists locally via GET .../variables?scope=local before deleting.
- If the variable lives in case scope, delete it via the case-instance variable endpoint instead.
- Handle 404 idempotently — deleting an already-deleted variable should be treated as success by the caller.
- Verify planItemInstanceId is from an active case instance.
Example fix
// before
delete("/plan-item-instances/" + id + "/variables/" + name); // may 404 if only case-scoped
// after
if (get("/plan-item-instances/" + id + "/variables/" + name + "?scope=local")) {
delete("/plan-item-instances/" + id + "/variables/" + name);
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check local existence
const vars = rest.get(`/cmmn-runtime/plan-item-instances/${id}/variables?scope=local`);
if (!vars.some(v => v.name === variableName)) return; // nothing local to delete Try / catch
try { api.deletePlanItemVariable(planItemId, name); }
catch (FlowableObjectNotFoundException e) {
if (e.getResourceClass() == VariableInstance.class) { log.info('already deleted or case-scoped'); return; }
throw e;
} Prevention
- Remember deleteVariable only targets LOCAL scope; case-scoped variables need the case-instance endpoint.
- Make deletes idempotent in workers (tolerate 404).
- Use optimistic locking or dedup keys to avoid concurrent double-deletes.
- Verify the plan item instance is still active before deleting.
When it happens
Trigger: DELETE /cmmn-runtime/plan-item-instances/{planItemInstanceId}/variables/{variableName} where the variable was never set locally, was already deleted, or exists only in case (global) scope.
Common situations: Assuming variables set on the case are visible as plan-item-local variables; double DELETE from concurrent workers; variable removed by a completed plan item; wrong planItemInstanceId (typo or from an ended case).
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Task '
- plan item instance ${planItemInstanceId} doesn't exist
- plan item instance ${planItemInstanceId} doesn't exist
- No plan item instance found for id
- No case instance found for id ${caseInstanceId}
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3c02d731e6a9f5e0.
Report an issue: GitHub.