flowable/flowable-engine · error · FlowableIllegalArgumentException
Invalid process definition id : null
Error message
Invalid process definition id : null
What it means
Flowable throws FlowableIllegalArgumentException when RuntimeService/RepositoryService APIs are called with a null process definition id. DeploymentManager.resolveById is the central lookup point; it validates the id before consulting the process definition cache or the database. The null check prevents downstream lookups (cache get, EntityManager.findById) from failing obscurely.
Solutions
- Log/inspect where the id originates and fix the upstream code that leaves it null
- Check you are passing the processDefinitionId, not the processInstanceId or deploymentId
- Only call the API when a definition id is actually needed (e.g. skip definition queries for standalone tasks)
- Guard with a null check before invoking the engine API
Example fix
// before
ProcessDefinition pd = repositoryService.getProcessDefinition(task.getProcessDefinitionId());
// after
if (task.getProcessDefinitionId() != null) {
ProcessDefinition pd = repositoryService.getProcessDefinition(task.getProcessDefinitionId());
} Defensive patterns
Strategy: validation
Validate before calling
if (processDefinitionId == null || processDefinitionId.isBlank()) {
throw new IllegalArgumentException("processDefinitionId must be provided");
}
repositoryService.getProcessDefinition(processDefinitionId); Type guard
boolean hasDefinitionId(Task t) { return t != null && t.getProcessDefinitionId() != null; } Prevention
- Never pass engine ids through nullable fields without checks
- Distinguish processDefinitionId vs processInstanceId vs deploymentId in your DTOs
- Log the id source when wiring engine calls
When it happens
Trigger: Calling runtimeService.startProcessInstanceById(null), taskService.createTaskQuery().processDefinitionId(null) with an id variable that was never assigned, or a resolver that returned null before being passed into an API that fetches a deployed process definition by id.
Common situations: A workflow variable or query result used as the definition id was null (e.g. task.getProcessDefinitionId() on a standalone task); a DTO field not populated; a caller passed a process instance id where a definition id was expected.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/b9c9d8bb5943b51d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/deploy/DeploymentManager.java:68
protected List<EngineDeployer> deployers;
protected ProcessEngineConfigurationImpl processEngineConfiguration;
protected ProcessDefinitionEntityManager processDefinitionEntityManager;
protected DeploymentEntityManager deploymentEntityManager;
public void deploy(DeploymentEntity deployment) {
deploy(deployment, null);
}
public void deploy(DeploymentEntity deployment, Map<String, Object> deploymentSettings) {
for (EngineDeployer deployer : deployers) {
deployer.deploy(deployment, deploymentSettings);
}
}
public ProcessDefinition findDeployedProcessDefinitionById(String processDefinitionId) {
if (processDefinitionId == null) {
throw new FlowableIllegalArgumentException("Invalid process definition id : null");
}
// first try the cache
ProcessDefinitionCacheEntry cacheEntry = processDefinitionCache.get(processDefinitionId);
ProcessDefinition processDefinition = cacheEntry != null ? cacheEntry.getProcessDefinition() : null;
if (processDefinition == null) {
processDefinition = processDefinitionEntityManager.findById(processDefinitionId);
if (processDefinition == null) {
throw new FlowableObjectNotFoundException("no deployed process definition found with id '" + processDefinitionId + "'", ProcessDefinition.class);
}
processDefinition = resolveProcessDefinition(processDefinition).getProcessDefinition();
}
return processDefinition;
}
public ProcessDefinition findDeployedLatestProcessDefinitionByKey(String processDefinitionKey) {
ProcessDefinition processDefinition = processDefinitionEntityManager.findLatestProcessDefinitionByKey(processDefinitionKey);View on GitHub (pinned to d6d39ce1c6)