flowable/flowable-engine · error · FlowableException

Cannot find the process definition to migrate to…

Error message

Cannot find the process definition to migrate to, identified by " + printProcessDefinitionIdentifierMessage(document)

What it means

When batch-migrating all instances of a process definition, Flowable resolves the target process definition from the migration document (by target id or key/version). If resolution returns null, it throws FlowableException with an identifier message describing what the document asked for, because nothing can be migrated without a valid target definition.

Solutions

  1. Verify the target definition exists via RepositoryService.createProcessDefinitionQuery().processDefinitionId(...) before migrating.
  2. Use key-based (latest version) targeting instead of a hard-coded definition id.
  3. Re-deploy the target BPMN to the environment where migration runs.
  4. Check tenant id alignment if using multi-tenancy.

Example fix

// before
document.migrateToProcessDefinitionId("orderProcess:4:9999"); // stale id
migrationService.migrateProcessInstancesOfProcessDefinition(srcId, document);

// after
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("orderProcess").latestVersion().singleResult();
document.migrateToProcessDefinitionId(pd.getId());
Defensive patterns

Strategy: validation

Validate before calling

ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
    .processDefinitionId(targetDefId).singleResult();
if (pd == null) throw new IllegalArgumentException("Target definition not deployed: " + targetDefId);

Try / catch

try {
    migrationService.migrateProcessInstancesOfProcessDefinition(srcId, document);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("Cannot find the process definition")) {
        logger.error("Target process definition missing: " + e.getMessage());
    }
}

Prevention

When it happens

Trigger: Calling migrateProcessInstancesOfProcessDefinition(sourceDefId, document, commandContext) where the document specifies a target processDefinitionId that doesn't exist, or a key/version combination with no deployed matching definition.

Common situations: Target deployment deleted or not promoted to the target environment; typo in target process definition key; specifying a version that was never deployed; tenant mismatch in multi-tenant setups.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java:399

            timerJob.setRepeat(processEngineConfiguration.getBatchStatusTimeCycleConfig());
            
            timerJobService.scheduleTimerJob(timerJob);
        }

        return batch;
    }

    @Override
    public void migrateProcessInstancesOfProcessDefinition(String procDefKey, int procDefVer, String procDefTenantId, ProcessInstanceMigrationDocument document, CommandContext commandContext) {
        ProcessDefinition processDefinition = resolveProcessDefinition(procDefKey, procDefVer, procDefTenantId, commandContext);
        migrateProcessInstancesOfProcessDefinition(processDefinition.getId(), document, commandContext);
    }

    @Override
    public void migrateProcessInstancesOfProcessDefinition(String processDefinitionId, ProcessInstanceMigrationDocument document, CommandContext commandContext) {
        ProcessDefinition processDefinition = resolveProcessDefinition(document, commandContext);
        if (processDefinition == null) {
            throw new FlowableException("Cannot find the process definition to migrate to, identified by " + printProcessDefinitionIdentifierMessage(document));
        }

        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        ProcessInstanceQueryImpl processInstanceQueryByProcessDefinitionId = new ProcessInstanceQueryImpl(commandContext, processEngineConfiguration).processDefinitionId(processDefinitionId);
        Set<String> processInstanceIdsToMigrate = document.getProcessInstanceIdsToMigrate();
        if (processInstanceIdsToMigrate != null && !processInstanceIdsToMigrate.isEmpty()) {
            processInstanceQueryByProcessDefinitionId.processInstanceIds(processInstanceIdsToMigrate);
        }
        ExecutionEntityManager executionEntityManager = processEngineConfiguration.getExecutionEntityManager();
        List<ProcessInstance> processInstances = executionEntityManager.findProcessInstanceByQueryCriteria(processInstanceQueryByProcessDefinitionId);

        for (ProcessInstance processInstance : processInstances) {
            doMigrateProcessInstance(processInstance, processDefinition, document, commandContext);
        }
    }

    @Override
    public void migrateProcessInstance(String processInstanceId, ProcessInstanceMigrationDocument document, CommandContext commandContext) {

View on GitHub (pinned to d6d39ce1c6)