flowable/flowable-engine · warning · FlowableIllegalArgumentException

Only one of 'timersOnly' or 'messagesOnly' can be provided.

Error message

Only one of 'timersOnly' or 'messagesOnly' can be provided.

What it means

The job collection query endpoint forbids combining the mutually exclusive filters 'timersOnly' and 'messagesOnly' in one request, throwing FlowableIllegalArgumentException. A job query can filter to timer jobs or message jobs, but not both in the same request.

Source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/management/JobCollectionResource.java:142

        }
        if (allRequestParams.containsKey("processDefinitionId")) {
            query.processDefinitionId(allRequestParams.get("processDefinitionId"));
        }
        if (allRequestParams.containsKey("elementId")) {
            query.elementId(allRequestParams.get("elementId"));
        }
        if (allRequestParams.containsKey("elementName")) {
            query.elementName(allRequestParams.get("elementName"));
        }
        if (allRequestParams.containsKey("handlerType")) {
            query.handlerType(allRequestParams.get("handlerType"));
        }
        if (allRequestParams.containsKey("handlerTypes")) {
            query.handlerTypes(Arrays.asList(allRequestParams.get("handlerTypes").split(",")));
        }
        if (allRequestParams.containsKey("timersOnly")) {
            if (allRequestParams.containsKey("messagesOnly")) {
                throw new FlowableIllegalArgumentException("Only one of 'timersOnly' or 'messagesOnly' can be provided.");
            }
            if (Boolean.parseBoolean(allRequestParams.get("timersOnly"))) {
                query.timers();
            }
        }
        if (allRequestParams.containsKey("messagesOnly") && Boolean.parseBoolean(allRequestParams.get("messagesOnly"))) {
            query.messages();
        }
        if (allRequestParams.containsKey("dueBefore")) {
            query.duedateLowerThan(RequestUtil.getDate(allRequestParams, "dueBefore"));
        }
        if (allRequestParams.containsKey("dueAfter")) {
            query.duedateHigherThan(RequestUtil.getDate(allRequestParams, "dueAfter"));
        }
        if (allRequestParams.containsKey("withException") && Boolean.parseBoolean(allRequestParams.get("withException"))) {
            query.withException();
        }
        if (allRequestParams.containsKey("exceptionMessage")) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Send only one of the two parameters in a single request.
  2. To get both timer and message jobs, issue two queries and merge results client-side.
  3. Omit both parameters to fetch all job types (or use handlerTypes for finer control).
  4. Fix any client code that blindly serializes both query params.

Example fix

// before
GET /management/jobs?timersOnly=true&messagesOnly=true
// after
GET /management/jobs?timersOnly=true
// (separate call for messages)
GET /management/jobs?messagesOnly=true
Defensive patterns

Strategy: validation

Validate before calling

const params = new URLSearchParams();
if (timersOnly && messagesOnly) throw new Error('timersOnly and messagesOnly are mutually exclusive');
if (timersOnly) params.set('timersOnly', 'true');
if (messagesOnly) params.set('messagesOnly', 'true');

Try / catch

try {
  return await listJobs(params);
} catch (e) {
  if (e.status === 400 && /timersOnly|messagesOnly/.test(e.message)) {
    const [a, b] = await Promise.all([listJobs({timersOnly:true}), listJobs({messagesOnly:true})]);
    return [...a, ...b];
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /management/jobs?timersOnly=true&messagesOnly=true (both request parameters present at once).

Common situations: Generic query-builder UIs that append every known filter, copy-pasted query strings, or code paths that always add both flags regardless of user intent.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/89d78685aa7da990. Report an issue: GitHub.