flowable/flowable-engine · error · FlowableIllegalArgumentException
Can not activate job ${jobId}. Parent is suspended.
Error message
Can not activate job ${jobId}. Parent is suspended. What it means
Flowable suspends process definitions/instances hierarchically: a job whose parent (process instance, process definition, or deployment) is suspended cannot be individually activated. JobServiceImpl.activateSuspendedJob() consults the JobParentStateResolver and throws FlowableIllegalArgumentException if the job's parent is still suspended, preventing an inconsistent state where an active job belongs to a suspended parent.
Source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/JobServiceImpl.java:130
}
@Override
public List<DeadLetterJobEntity> findDeadLetterJobsByProcessInstanceId(String processInstanceId) {
return getDeadLetterJobEntityManager().findJobsByProcessInstanceId(processInstanceId);
}
@Override
public void updateAllJobTypesTenantIdForDeployment(String deploymentId, String newTenantId) {
getJobEntityManager().updateJobTenantIdForDeployment(deploymentId, newTenantId);
getTimerJobEntityManager().updateJobTenantIdForDeployment(deploymentId, newTenantId);
getSuspendedJobEntityManager().updateJobTenantIdForDeployment(deploymentId, newTenantId);
getDeadLetterJobEntityManager().updateJobTenantIdForDeployment(deploymentId, newTenantId);
}
@Override
public AbstractRuntimeJobEntity activateSuspendedJob(SuspendedJobEntity job) {
if (configuration.getJobParentStateResolver().isSuspended(job)) {
throw new FlowableIllegalArgumentException("Can not activate job "+ job.getId() +". Parent is suspended.");
}
return getJobManager().activateSuspendedJob(job);
}
@Override
public SuspendedJobEntity moveJobToSuspendedJob(AbstractRuntimeJobEntity job) {
return getJobManager().moveJobToSuspendedJob(job);
}
@Override
public AbstractRuntimeJobEntity moveJobToDeadLetterJob(AbstractRuntimeJobEntity job) {
return getJobManager().moveJobToDeadLetterJob(job);
}
@Override
public JobEntity createJob() {
return getJobEntityManager().create();
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Activate the parent first: call managementService.activateProcessInstanceById(pid) or activateProcessDefinitionById(id) before activating the job
- Lift the suspension at the level it was applied (process definition or deployment) using the matching activate* command
- If per-job activation is intended, ensure the parent was never suspended or has already been re-activated, then retry
Example fix
// before managementService.activateJob(jobId); // parent still suspended -> error // after managementService.activateProcessInstanceById(processInstanceId); managementService.activateJob(jobId);
Defensive patterns
Strategy: try-catch
Validate before calling
// Check parent state before activating
boolean suspended = managementService.createProcessInstanceQuery()
.processInstanceId(pid)
.suspended()
.count() > 0;
if (suspended) {
managementService.activateProcessInstanceById(pid);
} Try / catch
try {
managementService.activateJob(jobId);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Parent is suspended")) {
// activate parent, then retry once
} else {
throw e;
}
} Prevention
- Track which level (job/instance/definition/deployment) you suspended at and resume at the same level
- Check suspension state via queries before per-job activation
- Avoid mixing suspendAll-style bulk suspension with per-job activation in automation
When it happens
Trigger: Calling managementService.activateJob(jobId) (or activateJobByProcessInstanceId etc.) for a job whose owning process instance or process definition is currently suspended; trying to activate a job while its deployment-level suspension is still in effect.
Common situations: Administrators resuming a single job after a suspendAll() without first lifting the suspension on the parent process instance/definition; scripted recovery jobs that activate jobs while the whole deployment remains suspended; race conditions where suspension and activation happen concurrently.
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
- Task ${taskId} is already deleted
- a suspended
- Child task variables can only be set when starting a plan it
- Child form variables can only be set when starting a plan it
- The source and the target tenant ids must be different.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/329e68bf7cf16bef.
Report an issue: GitHub.