flowable/flowable-engine · warning · FlowableConflictException
Process definition with id '" + processDefinition.getId() +…
Error message
Process definition with id '" + processDefinition.getId() + " ' is already active
What it means
activateProcessDefinition checks repositoryService.isProcessDefinitionSuspended first; if the definition is not suspended, activating it is a no-op conflict and Flowable throws FlowableConflictException (HTTP 409). This guards against redundant state transitions.
Solutions
- Check suspension state first (GET definition, suspended flag) and skip activation if already active
- Catch FlowableConflictException / HTTP 409 and treat as success in idempotent automation
- Use the date parameter for scheduled activation instead of repeated calls
Example fix
// before
put(id, {"action":"activate"}); // 409 if already active
// after
if (def.suspended) put(id, {"action":"activate"}); Defensive patterns
Strategy: validation
Validate before calling
const def = await api.getProcessDefinition(defId);
if (!def.suspended) return { skipped: true, reason: 'already active' }; Type guard
const needsActivation = (def) => def != null && def.suspended === true;
Try / catch
try { await api.activateProcessDefinition(defId); }
catch (e) { if (e.status === 409) return { skipped: true }; throw e; } Prevention
- Read the suspended flag before activating or suspending
- Make automation idempotent by treating 409 as success
- Use scheduled activation with a date instead of polling calls
When it happens
Trigger: PUT /repository/process-definitions/{id} with {"action":"activate"} on a definition that is already active.
Common situations: Retry logic re-sending activate after a first success; race between two administrators; scheduled activation scripts running twice.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Local variable ' ' is already present on plan item instance…
- Only allowed to update multiple variables in the same scope.
- Variable '
- Variable '" + name + "' is already present on execution '"…
- Variable ' ' is already present on task ' '.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ba2e331b90ba8c0f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ProcessDefinitionResource.java:228
} else {
formInfo = formRepositoryService.getFormModelByKey(startEvent.getFormKey(), processDefinition.getTenantId(),
processEngineConfiguration.isFallbackToDefaultTenant());
}
}
}
if (formInfo == null) {
// Definition found, but no form attached
throw new FlowableObjectNotFoundException("Process definition does not have a form defined: " + processDefinition.getId());
}
return formInfo;
}
protected ProcessDefinitionResponse activateProcessDefinition(ProcessDefinition processDefinition, boolean suspendInstances, Date date) {
if (!repositoryService.isProcessDefinitionSuspended(processDefinition.getId())) {
throw new FlowableConflictException("Process definition with id '" + processDefinition.getId() + " ' is already active");
}
repositoryService.activateProcessDefinitionById(processDefinition.getId(), suspendInstances, date);
ProcessDefinitionResponse response = restResponseFactory.createProcessDefinitionResponse(processDefinition);
// No need to re-fetch the ProcessDefinition, just alter the suspended
// state of the result-object
response.setSuspended(false);
return response;
}
protected ProcessDefinitionResponse suspendProcessDefinition(ProcessDefinition processDefinition, boolean suspendInstances, Date date) {
if (repositoryService.isProcessDefinitionSuspended(processDefinition.getId())) {
throw new FlowableConflictException("Process definition with id '" + processDefinition.getId() + " ' is already suspended");
}
repositoryService.suspendProcessDefinitionById(processDefinition.getId(), suspendInstances, date);
ProcessDefinitionResponse response = restResponseFactory.createProcessDefinitionResponse(processDefinition);View on GitHub (pinned to d6d39ce1c6)