flowable/flowable-engine · warning · FlowableObjectNotFoundException

Could not find a case instance with id '${caseInstanceId}'.

Error message

Could not find a case instance with id '${caseInstanceId}'.

What it means

FlowableObjectNotFoundException thrown when a historic case instance query by id returns no result. The REST layer converts a null singleResult() into a 404-style error because the requested historic case instance does not exist (or is not visible to the caller's history level).

Source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/caze/HistoricCaseInstanceBaseResource.java:302

        }
        
        return responseList;
    }
    
    protected HistoricCaseInstance getHistoricCaseInstanceFromRequest(String caseInstanceId) {
        HistoricCaseInstance caseInstance = getHistoricCaseInstanceFromRequestWithoutAccessCheck(caseInstanceId);

        if (restApiInterceptor != null) {
            restApiInterceptor.accessHistoryCaseInfoById(caseInstance);
        }
        
        return caseInstance;
    }

    protected HistoricCaseInstance getHistoricCaseInstanceFromRequestWithoutAccessCheck(String caseInstanceId) {
        HistoricCaseInstance caseInstance = historyService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstanceId).singleResult();
        if (caseInstance == null) {
            throw new FlowableObjectNotFoundException("Could not find a case instance with id '" + caseInstanceId + "'.", HistoricCaseInstance.class);
        }

        return caseInstance;
    }

    protected void addVariables(HistoricCaseInstanceQuery caseInstanceQuery, List<QueryVariable> variables) {
        for (QueryVariable variable : variables) {
            if (variable.getVariableOperation() == null) {
                throw new FlowableIllegalArgumentException("Variable operation is missing for variable: " + variable.getName());
            }
            if (variable.getVariableOperation() != QueryVariableOperation.EXISTS && variable.getVariableOperation() != QueryVariableOperation.NOT_EXISTS) {
                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)

Solutions

  1. Verify the caseInstanceId exists: query ACT_HI_CASEINST (SELECT * FROM ACT_HI_CASEINST WHERE ID_ = ?) or call historyService.createHistoricCaseInstanceQuery().caseInstanceId(id).count() first
  2. Check the engine's history level (process/history config) is high enough to record case instances
  3. Confirm the REST call targets the same database/schema the case was executed in
  4. Handle the 404 client-side and treat the id as expired; re-fetch the id from the case list endpoint

Example fix

// before
HistoricCaseInstance ci = historyService.createHistoricCaseInstanceQuery().caseInstanceId(id).singleResult(); // null -> REST 404
// after
long n = historyService.createHistoricCaseInstanceQuery().caseInstanceId(id).count();
if (n == 0) { throw new MyNotFoundException("Historic case " + id + " not found"); }
Defensive patterns

Strategy: validation

Validate before calling

long n = historyService.createHistoricCaseInstanceQuery().caseInstanceId(id).count();
if (n == 0) throw new IllegalArgumentException("Historic case instance not found: " + id);

Type guard

boolean historicCaseExists(String id) {
  return historyService.createHistoricCaseInstanceQuery().caseInstanceId(id).count() > 0;
}

Try / catch

try { ... } catch (FlowableObjectNotFoundException e) {
  log.warn("Historic case instance {} not found", id);
  return Optional.empty();
}

Prevention

When it happens

Trigger: GET on a historic case instance REST endpoint with a caseInstanceId that does not match any row in ACT_HI_CASEINST (wrong id, typo, purged history, or history level never recorded the case).

Common situations: Client caches case instance ids after history cleanup jobs ran; querying a runtime case id before completion when history level is 'none' or 'activity'; id taken from a different engine/database.

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


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