flowable/flowable-engine · error · FlowableException
Cannot execute operation because process definition '" +…
Error message
Cannot execute operation because process definition '" + processDefinition.getName() + "' (id=" + processDefinition.getId() + ") is suspended
What it means
Flowable throws this FlowableException when a command extending NeedsActiveProcessDefinitionCmd (e.g. start a process instance by id) targets a process definition that is currently suspended. Definitions are suspended/activated via RepositoryService, and all runtime operations against a suspended definition are blocked.
Solutions
- Reactivate with repositoryService.activateProcessDefinitionById(processDefinitionId) (optionally suspend/activate related instances too), then retry.
- Use a different active definition version: startProcessInstanceByKey with the latest active version instead of a suspended id.
- Check suspension up front: RepositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult().isSuspended().
- Catch FlowableException with message matching "is suspended" and return a clear business error to the caller.
Example fix
// before
runtimeService.startProcessInstanceById("suspended-def-id");
// after
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId("suspended-def-id").singleResult();
if (pd != null && !pd.isSuspended()) {
runtimeService.startProcessInstanceById(pd.getId());
} Defensive patterns
Strategy: validation
Validate before calling
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(defId).singleResult();
if (pd == null || pd.isSuspended()) { throw new IllegalStateException("Definition missing or suspended"); } Try / catch
try {
runtimeService.startProcessInstanceById(defId);
} catch (FlowableException e) {
if (e.getMessage().contains("is suspended")) {
repositoryService.activateProcessDefinitionById(defId);
return runtimeService.startProcessInstanceById(defId);
}
throw e;
} Prevention
- Start instances by key so Flowable resolves the latest active version.
- Monitor for suspended definitions after deployments.
- Automate suspend/activate pairs so definitions are never left suspended.
- Add integration tests that start instances after migration runs.
When it happens
Trigger: Calling RuntimeService.startProcessInstanceById(processDefinitionId) (or other NeedsActiveProcessDefinitionCmd subclasses) while the definition was suspended with RepositoryService.suspendProcessDefinitionById(...).
Common situations: Ops suspended a definition version to deploy a fix, but clients still start instances by that id; a suspended definition is the default/latest version so new starts fail; environment sync copied suspended state across environments.
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
- a suspended
- Can not activate job
- Cannot combine onlyInbound() with onlyOutbound() in the…
- Cannot combine onlyOutbound() with onlyInbound() in the…
- Cannot throw signal event
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/8350269a806c4371.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/NeedsActiveProcessDefinitionCmd.java:42
/**
* @author Joram Barrez
*/
public abstract class NeedsActiveProcessDefinitionCmd<T> implements Command<T>, Serializable {
private static final long serialVersionUID = 1L;
protected String processDefinitionId;
public NeedsActiveProcessDefinitionCmd(String processDefinitionId) {
this.processDefinitionId = processDefinitionId;
}
@Override
public T execute(CommandContext commandContext) {
ProcessDefinitionEntity processDefinition = ProcessDefinitionUtil.getProcessDefinitionFromDatabase(processDefinitionId);
if (processDefinition.isSuspended()) {
throw new FlowableException("Cannot execute operation because process definition '" + processDefinition.getName() + "' (id=" + processDefinition.getId() + ") is suspended");
}
return execute(commandContext, processDefinition);
}
/**
* Subclasses should implement this. The provided {@link ProcessDefinition} is guaranteed to be an active process definition (ie. not suspended).
*/
protected abstract T execute(CommandContext commandContext, ProcessDefinitionEntity processDefinition);
}
View on GitHub (pinned to d6d39ce1c6)