flowable/flowable-engine · error · FlowableObjectNotFoundException

Cannot find process definition with id

Error message

Cannot find process definition with id 

What it means

GetPotentialStarterUsersCmd.execute mirrors the groups variant: it loads the process definition by id and throws FlowableObjectNotFoundException if findById returns null. Starter users come from the definition's identity links, which cannot be read from a nonexistent definition. This fail-fast prevents a NullPointerException.

Solutions

  1. Query the definition first to confirm the id: createProcessDefinitionQuery().processDefinitionId(id).singleResult()
  2. Derive the id from the definition key at runtime instead of hardcoding
  3. Set the correct tenant context or add tenant filters to the definition query
  4. Check deployment history (repositoryService.createDeploymentQuery()) to confirm the definition still exists
  5. Handle FlowableObjectNotFoundException by returning an empty user list and logging the unknown id

Example fix

// before
List<User> users = repositoryService.getIdentityLinksForProcessDefinition(staleDefId);
// after
ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey(key).processDefinitionTenantId(tenant).latestVersion().singleResult();
List<User> users = (def != null)
    ? repositoryService.getIdentityLinksForProcessDefinition(def.getId())
    : Collections.emptyList();
Defensive patterns

Strategy: validation

Validate before calling

ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey(key).processDefinitionTenantId(tenant).latestVersion().singleResult();
if (def == null) throw new IllegalArgumentException("No deployed definition for key " + key);

Try / catch

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

Prevention

When it happens

Trigger: Calling the potential-starter-users API (RepositoryService.getIdentityLinksForProcessDefinition family) with a processDefinitionId that does not resolve — deleted definition, wrong environment, key-vs-id confusion, or tenant-specific definition not visible.

Common situations: After re-deploying a new version and using a stale id; querying a tenant's definition while running without tenant context; test ids used against a production database; ids read from a config file that drifted from the deployed models.

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

Appendix: source

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

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

    private static final long serialVersionUID = 1L;

    protected String processDefinitionId;

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

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public List<User> 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> userIds = new ArrayList<>();
        List<IdentityLink> identityLinks = (List) processDefinition.getIdentityLinks();
        for (IdentityLink identityLink : identityLinks) {
            if (identityLink.getUserId() != null && identityLink.getUserId().length() > 0) {

                if (!userIds.contains(identityLink.getUserId())) {
                    userIds.add(identityLink.getUserId());
                }
            }
        }

        if (userIds.size() > 0) {
            return identityService.createUserQuery().userIds(userIds).list();

View on GitHub (pinned to d6d39ce1c6)