flowable/flowable-engine · error · FlowableIllegalArgumentException
Job <jobId> parent is not process instance
Error message
Job <jobId> parent is not process instance
What it means
DefaultProcessJobParentStateResolver.isSuspended(Job) only supports jobs whose parent is a process instance. If the job's processInstanceId is empty (e.g. a standalone/async-executor job with no owning process instance) it throws FlowableIllegalArgumentException, because the resolver would otherwise dereference a null ProcessInstance. It is a guard that this parent-state resolver is only used for process-scoped jobs.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/DefaultProcessJobParentStateResolver.java:35
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.job.api.Job;
import org.flowable.job.service.InternalJobParentStateResolver;
/**
* @author martin.grofcik
*/
public class DefaultProcessJobParentStateResolver implements InternalJobParentStateResolver {
protected ProcessEngineConfigurationImpl processEngineConfiguration;
public DefaultProcessJobParentStateResolver(ProcessEngineConfigurationImpl processEngineConfiguration) {
this.processEngineConfiguration = processEngineConfiguration;
}
@Override
public boolean isSuspended(Job job) {
if (StringUtils.isEmpty(job.getProcessInstanceId())) {
throw new FlowableIllegalArgumentException("Job " + job.getId() + " parent is not process instance");
}
ProcessInstance processInstance = this.processEngineConfiguration.getRuntimeService().createProcessInstanceQuery().processInstanceId(job.getProcessInstanceId()).singleResult();
return processInstance.isSuspended();
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Ensure the job actually belongs to a process instance before invoking suspension logic on it.
- Check StringUtils.isEmpty(job.getProcessInstanceId()) in your own code first and use a job-specific suspension path for standalone jobs.
- If the job should have a process instance, investigate why the parent is missing (corrupt/migrated ACT_RU_JOB rows).
Example fix
// before
boolean suspended = jobParentStateResolver.isSuspended(job); // throws for standalone jobs
// after
if (StringUtils.isNotEmpty(job.getProcessInstanceId())) {
suspended = jobParentStateResolver.isSuspended(job);
} else {
suspended = managementService.isJobSuspended(job.getId());
} Defensive patterns
Strategy: validation
Validate before calling
if (job == null || StringUtils.isEmpty(job.getProcessInstanceId())) {
throw new IllegalArgumentException("Job has no owning process instance; use job-level suspension API");
} Type guard
boolean isProcessScopedJob(Job job) { return job != null && StringUtils.isNotEmpty(job.getProcessInstanceId()); } Try / catch
try {
suspended = resolver.isSuspended(job);
} catch (FlowableIllegalArgumentException e) {
suspended = false; // or fall back to job-level state lookup
log.warn("Job {} has no process instance parent", job.getId());
} Prevention
- Verify a job's processInstanceId before using process-instance parent resolvers
- Handle standalone/async jobs with dedicated job management APIs
- Check ACT_RU_JOB.PROCESS_INSTANCE_ID_ data integrity after migrations
When it happens
Trigger: Suspending/resuming or checking suspension state of a Job whose getProcessInstanceId() returns null or empty — e.g. a timer or async job created outside a process instance, or management API calls on such jobs routed through this resolver.
Common situations: Calling ManagementService or JobService suspension APIs on standalone jobs (external worker/async history jobs) after upgrading Flowable versions where job parenting changed; data migrated from another engine where PROCESS_INSTANCE_ID_ is null.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Could not start process instance with business key ${key}
- There is no batch with the id ${configuration}
- There is no batch part with the id ${configuration}
- There is no batch with the id ${configuration}
- Timer job with id '' doesn't have an exception stacktrace.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a5c793e7209f2ab4.
Report an issue: GitHub.