flowable/flowable-engine · error · FlowableObjectNotFoundException

No process definition found for id =

Error message

No process definition found for id = '${processDefinitionId}'

What it means

StartProcessInstanceCmd could not resolve the given processDefinitionId to a deployed process definition. Flowable looks the id up in the DeploymentManager cache/backing store and throws FlowableObjectNotFoundException when nothing matches.

Solutions

  1. Fetch valid ids at runtime via RepositoryService.createProcessDefinitionQuery().list() instead of hardcoding
  2. Verify the id string equals the ACT_RE_PROCDEF.ID_ value in the connected database
  3. Re-deploy the BPMN resource if the definition was deleted
  4. Ensure the app connects to the intended Flowable database/environment

Example fix

// before
runtimeService.startProcessInstanceById("myProcess:1:4");
// after
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("myProcess").latestVersion().singleResult();
if (pd != null) runtimeService.startProcessInstanceById(pd.getId());
Defensive patterns

Strategy: validation

Validate before calling

ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
    .processDefinitionId(processDefinitionId).singleResult();
if (pd == null) throw new IllegalArgumentException("unknown process definition id: " + processDefinitionId);

Type guard

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

Try / catch

try {
    runtimeService.startProcessInstanceById(id);
} catch (FlowableObjectNotFoundException e) {
    // resolve latest id via ProcessDefinitionQuery and retry
}

Prevention

When it happens

Trigger: Calling RuntimeService.startProcessInstanceById(id) (or the builder equivalent) with an id that is not deployed, was deleted, or from a different database/tenant environment.

Common situations: Hardcoded ids copied between environments (dev vs prod ids differ); definition deleted via repositoryService.deleteDeployment; lookup against a fresh/empty Flowable 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/ddcc3fde4e7d0489. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/StartProcessInstanceCmd.java:272

            callbackId, callbackType, referenceId, referenceType, ownerId, assigneeId, stageInstanceId, true);
    }

    protected boolean hasStartFormData() {
        return startFormVariables != null || outcome != null;
    }

    protected boolean hasFormData() {
        return hasStartFormData() || extraFormInfo != null;
    }

    protected ProcessDefinition getProcessDefinition(ProcessEngineConfigurationImpl processEngineConfiguration, CommandContext commandContext) {
        // Find the process definition
        ProcessDefinition processDefinition = null;
        if (processDefinitionId != null) {
            DeploymentManager deploymentCache = processEngineConfiguration.getDeploymentManager();
            processDefinition = deploymentCache.findDeployedProcessDefinitionById(processDefinitionId);
            if (processDefinition == null) {
                throw new FlowableObjectNotFoundException("No process definition found for id = '" + processDefinitionId + "'", ProcessDefinition.class);
            }

        } else if (processDefinitionKey != null) {
            processDefinition = processEngineConfiguration.getProcessInstanceHelper()
                    .resolveProcessDefinition(processDefinitionKey, tenantId,
                            fallbackToDefaultTenant || processEngineConfiguration.isFallbackToDefaultTenant(),
                            processDefinitionParentDeploymentId, processEngineConfiguration);

            if (tenantId != null && !ProcessEngineConfiguration.NO_TENANT_ID.equals(tenantId)
                    && !tenantId.equals(processDefinition.getTenantId())) {
                // Process definition comes from the fallback to the default tenant
                overrideDefinitionTenantId = tenantId;
            }

        } else {
            throw new FlowableIllegalArgumentException("processDefinitionKey and processDefinitionId are null");
        }
        return processDefinition;

View on GitHub (pinned to d6d39ce1c6)