flowable/flowable-engine · error · FlowableIllegalArgumentException
Cannot combine onlyExternalWorkers() with onlyMessages() in…
Error message
Cannot combine onlyExternalWorkers() with onlyMessages() in the same query
What it means
SuspendedJobQueryImpl.timers() throws FlowableIllegalArgumentException when onlyExternalWorkers was already set. The message reads 'Cannot combine onlyExternalWorkers() with onlyMessages()' (a slightly misleading copy in the source), but the check fires inside timers() when the query is restricted to external-worker jobs. Job-kind filters cannot be combined on a single suspended-job query.
Solutions
- Use either externalWorkers() or timers(), never both, per query.
- Issue separate queries for timer jobs and external-worker jobs and union the results.
- Reorder or delete the conflicting setter in the chain.
Example fix
// before query.externalWorkers().timers(); // throws in timers() // after List<Job> jobs = new ArrayList<>(); jobs.addAll(jobService.createSuspendedJobQuery().externalWorkers().list()); jobs.addAll(jobService.createSuspendedJobQuery().timers().list());
Defensive patterns
Strategy: try-catch
Validate before calling
if (wantTimers && wantExternalWorkers) {
throw new IllegalArgumentException("Query either timers or externalWorker jobs, not both");
} Type guard
boolean safeTimersCall(boolean externalWorkersSet) { return !externalWorkersSet; } Try / catch
try {
q.externalWorkers().timers();
} catch (FlowableIllegalArgumentException e) {
// run one query per kind and merge
} Prevention
- Model job-kind as a single enum (TIMER|MESSAGE|EXTERNAL_WORKER) in your selection logic so only one can be chosen.
- Apply the kind filter last, based on the enum, exactly once.
- Note the error text can be misleading; check which setter actually threw.
When it happens
Trigger: Chaining .externalWorkers().timers() on the same SuspendedJobQueryImpl, including inside or() blocks, to try to fetch both timer and external-worker suspended jobs in one query.
Common situations: External-worker (async executor) monitoring code that also wants timer jobs and tries to reuse one query object; migration from older Flowable versions where external-worker filters did not exist and new code combined flags incorrectly.
Related errors
- Cannot combine onlyMessages() with onlyExternalWorkers() in…
- Cannot combine onlyTimers() with onlyMessages() in the same…
- Cannot combine onlyTimers() with onlyMessages() in the same…
- Cannot combine onlyTimers() with onlyMessages() in the same…
- Provided correlationId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/149b35c5df447891.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/SuspendedJobQueryImpl.java:446
@Override
public SuspendedJobQueryImpl executable() {
if (inOrStatement) {
this.currentOrQueryObject.executable = true;
} else {
executable = true;
}
return this;
}
@Override
public SuspendedJobQueryImpl timers() {
if (onlyMessages) {
throw new FlowableIllegalArgumentException("Cannot combine onlyTimers() with onlyMessages() in the same query");
}
if (onlyExternalWorkers) {
throw new FlowableIllegalArgumentException("Cannot combine onlyExternalWorkers() with onlyMessages() in the same query");
}
if (inOrStatement) {
this.currentOrQueryObject.onlyTimers = true;
} else {
this.onlyTimers = true;
}
return this;
}
@Override
public SuspendedJobQueryImpl messages() {
if (onlyTimers) {
throw new FlowableIllegalArgumentException("Cannot combine onlyTimers() with onlyMessages() in the same query");
}
if (onlyExternalWorkers) {
throw new FlowableIllegalArgumentException("Cannot combine onlyExternalWorkers() with onlyMessages() in the same query");
}View on GitHub (pinned to d6d39ce1c6)