flowable/flowable-engine · error · FlowableException

ProcessDefinition does not exists

Error message

ProcessDefinition <processDefinitionId> does not exists

What it means

DynamicBpmnServiceImpl.getDynamicProcessDefinitionSummary() aggressively verifies the process definition exists by loading its BPMN model. When GetBpmnModelCmd returns null (no such process definition id), it throws FlowableException, since the method is documented as only valid for existing definitions.

Solutions

  1. Verify the id exists via repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult() before calling
  2. Re-fetch the id from the repository instead of a cached/stale value
  3. Catch FlowableException and treat it as 'definition not found' in the caller

Example fix

// before
ProcessDefinitionSummary summary = dynamicBpmnService.getDynamicProcessDefinitionSummary(id);
// after
if (repositoryService.createProcessDefinitionQuery().processDefinitionId(id).count() > 0) {
    ProcessDefinitionSummary summary = dynamicBpmnService.getDynamicProcessDefinitionSummary(id);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (repositoryService.createProcessDefinitionQuery().processDefinitionId(id).count() == 0) {
    throw new IllegalStateException("Unknown process definition: " + id);
}
ProcessDefinitionSummary s = dynamicBpmnService.getDynamicProcessDefinitionSummary(id);

Type guard

boolean definitionExists(String id, RepositoryService rs) {
    return id != null && rs.createProcessDefinitionQuery().processDefinitionId(id).count() > 0;
}

Try / catch

try {
    summary = dynamicBpmnService.getDynamicProcessDefinitionSummary(id);
} catch (FlowableException e) {
    // treat as definition-not-found; refresh id or surface 404
}

Prevention

When it happens

Trigger: Calling getDynamicProcessDefinitionSummary with an id that was never deployed, was deleted, or contains a typo; using a stale id after redeployment with a new id; calling before the deployment transaction committed.

Common situations: Referenced process definition removed by a cleanup job; wrong tenant or engine instance; ids copied between test/production repositories; caching of deleted definition ids.

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/56787ad526527a31. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/DynamicBpmnServiceImpl.java:463

    }

    @Override
    public void resetProperty(String elementId, String property, ObjectNode infoNode) {
        ObjectNode path = (ObjectNode) infoNode.path(BPMN_NODE).path(elementId);
        if (!path.isMissingNode()) {
            path.remove(property);
        }
    }

    @Override
    public DynamicProcessDefinitionSummary getDynamicProcessDefinitionSummary(String processDefinitionId) {
        ObjectNode infoNode = getProcessDefinitionInfo(processDefinitionId);
        ObjectMapper objectMapper = configuration.getObjectMapper();
        BpmnModel bpmnModel = commandExecutor.execute(new GetBpmnModelCmd(processDefinitionId));

        // aggressive exception. this method should not be called if the process definition does not exists.
        if (bpmnModel == null) {
            throw new FlowableException("ProcessDefinition " + processDefinitionId + " does not exists");
        }

        // to avoid redundant null checks we create an new node
        if (infoNode == null) {
            infoNode = configuration.getObjectMapper().createObjectNode();
            createOrGetBpmnNode(infoNode);
        }

        return new DynamicProcessDefinitionSummary(bpmnModel, infoNode, objectMapper);
    }

    protected void setElementProperty(String id, String propertyName, String propertyValue, ObjectNode infoNode) {
        ObjectNode bpmnNode = createOrGetBpmnNode(infoNode);
        if (!bpmnNode.has(id)) {
            bpmnNode.putObject(id);
        }

        ((ObjectNode) bpmnNode.get(id)).put(propertyName, propertyValue);

View on GitHub (pinned to d6d39ce1c6)