flowable/flowable-engine · error · FlowableIllegalArgumentException

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

Error message

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

What it means

SuspendedJobCollectionResource.getJobs validates query parameters for listing suspended jobs. Because timersOnly and messagesOnly are mutually exclusive filters, providing both request parameters raises FlowableIllegalArgumentException with this message. The API deliberately rejects the ambiguous combination instead of merging filters.

Solutions

  1. Send only one of timersOnly or messagesOnly in the request
  2. If you want both timers and messages, omit both parameters (default returns all suspended jobs)
  3. Fix the client-side query builder to make the two options mutually exclusive in the UI/logic
  4. Filter client-side if you truly need both sets in one call: fetch all and filter by job type

Example fix

// before
GET /management/suspended-jobs?timersOnly=true&messagesOnly=true
// after
GET /management/suspended-jobs?timersOnly=true
Defensive patterns

Strategy: validation

Validate before calling

function buildSuspendedJobsQuery(params) {
  if (params.timersOnly !== undefined && params.messagesOnly !== undefined) {
    throw new Error("Only one of 'timersOnly' or 'messagesOnly' can be provided.");
  }
  return new URLSearchParams(Object.entries(params)).toString();
}

Try / catch

try {
  return fetchSuspendedJobs(params);
} catch (e) {
  if (String(e.message).includes("timersOnly")) {
    return fetchSuspendedJobs({ ...params, messagesOnly: undefined });
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /management/suspended-jobs?timersOnly=true&messagesOnly=true (both parameters present in the request, regardless of value, since the check is containsKey on either parameter name).

Common situations: Client builds query string by appending all configured filters without removing the other; a UI that lets users tick both 'timers only' and 'messages only'; copied cURL commands with leftover parameters.

Related errors


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

Appendix: source

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

        }
        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("executable")) {
            query.executable();
        }
        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("withRetriesLeft") && Boolean.parseBoolean(allRequestParams.get("withRetriesLeft"))) {

View on GitHub (pinned to d6d39ce1c6)