flowable/flowable-engine · error · FlowableObjectNotFoundException

Historic variable instance '' could not be found.

Error message

Historic variable instance '' could not be found.

What it means

Flowable's history REST API looks up a historic variable instance by its id via historyService.createHistoricVariableInstanceQuery().id(varInstanceId). When the query returns no result, getVariableFromRequest throws FlowableObjectNotFoundException. This means no historic variable instance exists in the ACT_HI_VARINST table with the supplied id.

Solutions

  1. Verify the variableInstanceId against the ACT_HI_VARINST table (SELECT * FROM ACT_HI_VARINST WHERE ID_ = '<id>') or by listing GET /history/historic-variable-instances.
  2. Check the process engine's history level (e.g. 'audit' or 'full'); at level 'none' variables are not recorded in history, so re-run the process with a higher history level.
  3. Confirm you are querying the same database/schema and tenant the process ran in.
  4. Ensure history cleanup (flowable.history-cleaning settings) has not removed the instance.

Example fix

// before: guessing the id
RestVariable v = client.get("/history/historic-variable-instances/1234/data");
// after: fetch ids from the history query first
List<HistoricVariableInstance> vars = historyService.createHistoricVariableInstanceQuery()
    .processInstanceId(pid).list();
vars.stream()
    .filter(v -> "orderTotal".equals(v.getVariableName()))
    .findFirst()
    .ifPresent(v -> client.get("/history/historic-variable-instances/" + v.getId() + "/data"));
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = !client.list("/history/historic-variable-instances?variableInstanceId=" + id).isEmpty();

Try / catch

try {
    RestVariable v = client.get("/history/historic-variable-instances/" + id + "/data");
} catch (HttpClientErrorException e) {
    if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
        log.warn("Historic variable instance {} not found (purged or wrong id)", id);
    } else throw e;
}

Prevention

When it happens

Trigger: GET /history/historic-variable-instances/{variableInstanceId} (with or without ?includeBinary=true, or the /data sub-resource) where the variableInstanceId does not match any row in the historic variable instance table.

Common situations: Using a runtime variable id instead of a historic variable instance id; referencing a variable whose history level did not record variables (history level 'none'); data purged or cleaned by history cleanup jobs; typo'd or truncated id copied from logs; variable from a different Flowable database/tenant.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/e14e79186324710c. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricVariableInstanceDataResource.java:97

                result = buffer.toByteArray();
                response.setContentType("application/x-java-serialized-object");

            } else {
                throw new FlowableObjectNotFoundException("The variable does not have a binary data stream.", null);
            }
            return result;

        } catch (IOException ioe) {
            // Re-throw IOException
            throw new FlowableException("Unexpected exception getting variable data", ioe);
        }
    }

    public RestVariable getVariableFromRequest(boolean includeBinary, String varInstanceId) {
        HistoricVariableInstance varObject = historyService.createHistoricVariableInstanceQuery().id(varInstanceId).singleResult();

        if (varObject == null) {
            throw new FlowableObjectNotFoundException("Historic variable instance '" + varInstanceId + "' could not be found.", VariableInstanceEntity.class);
        } else {
            
            if (restApiInterceptor != null) {
                restApiInterceptor.accessHistoryVariableInfoById(varObject);
            }
            
            return restResponseFactory.createRestVariable(varObject.getVariableName(), varObject.getValue(), null, varInstanceId, RestResponseFactory.VARIABLE_HISTORY_VARINSTANCE, includeBinary);
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)