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
- Send only one of timersOnly or messagesOnly in the request
- If you want both timers and messages, omit both parameters (default returns all suspended jobs)
- Fix the client-side query builder to make the two options mutually exclusive in the UI/logic
- 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
- In UIs, make 'timers only' and 'messages only' a mutually exclusive radio group, not independent checkboxes
- Strip the opposite parameter in query-builder helpers when one is set
- Remember the check is on parameter presence (containsKey), so even timersOnly=false with messagesOnly present throws
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
- Only one of 'timersOnly' or 'messagesOnly' can be provided.
- A request body was expected when executing the form submit.
- Attachment name is required.
- Error converting request body to RestVariable instance
- Id cannot be null.
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)