flowable/flowable-engine · error · FlowableObjectNotFoundException
Historic variable instance
Error message
Historic variable instance '${varInstanceId}' couldn't be found. What it means
Thrown when querying a CMMN variable instance by id (GET /cmmn-runtime/variable-instances/{varInstanceId}) and the runtimeService.createVariableInstanceQuery() returns no row for that id. Despite the message saying 'Historic', this resource actually queries live runtime variable instances, so a variable that is historical-only or deleted cannot be found.
Solutions
- Confirm the variable instance id via GET /cmmn-runtime/variable-instances?... filters instead of assuming a stored id
- If the variable is historical, use the history endpoints (query historic variable instances) rather than runtime
- Verify the id was created in the same engine/database the REST app points to
- Handle 404 gracefully and refresh the variable list for the owning case/task
Defensive patterns
Strategy: try-catch
Validate before calling
const list = await fetch(`/cmmn-runtime/variable-instances?task-id=${taskId}`).then(r => r.json()); const exists = list.data.some(v => v.id === varInstanceId); Type guard
function isRuntimeVariableInstance(v) { return v != null && typeof v.id === 'string' && typeof v.name === 'string'; } Try / catch
try { return await getVariableInstance(varInstanceId); } catch (e) { if (e.status === 404) { return null; } throw e; } Prevention
- Do not persist runtime variable-instance ids long-term; re-query by task/case id instead
- Distinguish runtime vs historic variable ids
- Verify you are querying the same engine/database the id was created in
When it happens
Trigger: GET /cmmn-runtime/variable-instances/{id} with an id that does not exist, references an already-deleted variable, or an id from the historic variable instance table rather than the runtime table.
Common situations: Caller stores variable-instance ids from an old case instance that has completed; mixing up historic-variable-instance ids with runtime ones; typo or wrong engine/database queried.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Case instance ' ' doesn't have a variable with name: ' '.
- Could not find a case instance
- Could not find a plan item instance
- Execution ' ' does not have a variable ' ' in scope
- Historic process instance '" + processInstanceId + "'…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ee03b6406016259f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/variable/VariableInstanceBaseResource.java:107
}
if (queryRequest.getVariables() != null) {
addVariables(query, queryRequest.getVariables());
}
if (restApiInterceptor != null) {
restApiInterceptor.accessVariableInfoWithQuery(query, queryRequest);
}
return paginateList(allRequestParams, queryRequest, query, "variableName", allowedSortProperties,
restResponseFactory::createVariableInstanceResponseList);
}
public RestVariable getVariableFromRequest(boolean includeBinary, String varInstanceId) {
VariableInstance varObject = runtimeService.createVariableInstanceQuery().id(varInstanceId).singleResult();
if (varObject == null) {
throw new FlowableObjectNotFoundException("Historic variable instance '" + varInstanceId + "' couldn't be found.", VariableInstanceEntity.class);
} else {
if (restApiInterceptor != null) {
restApiInterceptor.accessVariableInfoById(varObject);
}
return restResponseFactory.createRestVariable(varObject.getName(), varObject.getValue(), null, varInstanceId, CmmnRestResponseFactory.VARIABLE_HISTORY_VARINSTANCE, includeBinary);
}
}
protected void addVariables(VariableInstanceQuery variableInstanceQuery, List<QueryVariable> variables) {
for (QueryVariable variable : variables) {
if (variable.getVariableOperation() == null) {
throw new FlowableIllegalArgumentException("Variable operation is missing for variable: " + variable.getName());
}
if (variable.getValue() == null) {
throw new FlowableIllegalArgumentException("Variable value is missing for variable: " + variable.getName());
}
boolean nameLess = variable.getName() == null;View on GitHub (pinned to d6d39ce1c6)