flowable/flowable-engine · error · FlowableObjectNotFoundException

Cannot find process definition with id

Error message

Cannot find process definition with id 

What it means

GetPotentialStarterGroupsCmd.execute loads the ProcessDefinitionEntity by id and throws FlowableObjectNotFoundException when not found. Potential starter groups are derived from the definition's identity links, so the definition must exist. Throwing avoids NPE on processDefinition.getIdentityLinks().

Solutions

  1. Validate the definition exists: repositoryService.createProcessDefinitionQuery().processDefinitionId(defId).singleResult()
  2. Look up the id from the key: .processDefinitionKey(key).latestVersion().singleResult() then use its getId()
  3. Include the tenant in the query if running multi-tenant (.processDefinitionTenantId) or use TenantContext
  4. Confirm the deployment was not cascade-deleted (check ACT_RE_DEPLOYMENT)
  5. Catch FlowableObjectNotFoundException and return empty starter groups with a warning

Example fix

// before
List<Group> groups = repositoryService.getIdentityLinksForProcessDefinition(defId); // wrong id type
// after
ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("orderProcess").latestVersion().singleResult();
List<Group> groups = repositoryService.getIdentityLinksForProcessDefinition(def.getId());
Defensive patterns

Strategy: validation

Validate before calling

ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
    .processDefinitionId(defId).singleResult();
if (def == null) {
  def = repositoryService.createProcessDefinitionQuery()
    .processDefinitionLatestVersion().processDefinitionTenantId(tenant)
    .processDefinitionKey(key).singleResult();
}

Try / catch

try {
  List<Group> groups = repositoryService.getIdentityLinksForProcessDefinition(defId);
} catch (FlowableObjectNotFoundException e) {
  groups = Collections.emptyList();
}

Prevention

When it happens

Trigger: Calling RepositoryService.getIdentityLinksForProcessDefinition-style potential-starter API, e.g. repositoryService.getIdentityLinksForProcessDefinition(defId) routed to this command, with a defId absent from ACT_RE_PROCDEF (typo, deleted deployment, wrong tenant/db).

Common situations: Definition id captured before a redeploy replaced ids; passing process key instead of id; multi-tenant apps querying without the correct tenant; environment mismatch between dev and prod.

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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetPotentialStarterGroupsCmd.java:48

 * @author Tijs Rademakers
 */
public class GetPotentialStarterGroupsCmd implements Command<List<Group>>, Serializable {

    private static final long serialVersionUID = 1L;

    protected String processDefinitionId;

    public GetPotentialStarterGroupsCmd(String processDefinitionId) {
        this.processDefinitionId = processDefinitionId;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public List<Group> execute(CommandContext commandContext) {
        ProcessDefinitionEntity processDefinition = CommandContextUtil.getProcessDefinitionEntityManager(commandContext).findById(processDefinitionId);

        if (processDefinition == null) {
            throw new FlowableObjectNotFoundException("Cannot find process definition with id " + processDefinitionId, ProcessDefinition.class);
        }

        IdentityService identityService = CommandContextUtil.getProcessEngineConfiguration(commandContext).getIdentityService();

        List<String> groupIds = new ArrayList<>();
        List<IdentityLink> identityLinks = (List) processDefinition.getIdentityLinks();
        for (IdentityLink identityLink : identityLinks) {
            if (identityLink.getGroupId() != null && identityLink.getGroupId().length() > 0) {

                if (!groupIds.contains(identityLink.getGroupId())) {
                    groupIds.add(identityLink.getGroupId());
                }
            }
        }

        if (groupIds.size() > 0) {
            return identityService.createGroupQuery().groupIds(groupIds).list();

View on GitHub (pinned to d6d39ce1c6)