{"record":{"id":"89d78685aa7da990","repo":"flowable/flowable-engine","slug":"only-one-of-timersonly-or-messagesonly-can-be-89d786","errorCode":null,"errorMessage":"Only one of 'timersOnly' or 'messagesOnly' can be provided.","messagePattern":"Only one of 'timersOnly' or 'messagesOnly' can be provided\\.","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"warning","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/management/JobCollectionResource.java","lineNumber":142,"sourceCode":"        }\n        if (allRequestParams.containsKey(\"processDefinitionId\")) {\n            query.processDefinitionId(allRequestParams.get(\"processDefinitionId\"));\n        }\n        if (allRequestParams.containsKey(\"elementId\")) {\n            query.elementId(allRequestParams.get(\"elementId\"));\n        }\n        if (allRequestParams.containsKey(\"elementName\")) {\n            query.elementName(allRequestParams.get(\"elementName\"));\n        }\n        if (allRequestParams.containsKey(\"handlerType\")) {\n            query.handlerType(allRequestParams.get(\"handlerType\"));\n        }\n        if (allRequestParams.containsKey(\"handlerTypes\")) {\n            query.handlerTypes(Arrays.asList(allRequestParams.get(\"handlerTypes\").split(\",\")));\n        }\n        if (allRequestParams.containsKey(\"timersOnly\")) {\n            if (allRequestParams.containsKey(\"messagesOnly\")) {\n                throw new FlowableIllegalArgumentException(\"Only one of 'timersOnly' or 'messagesOnly' can be provided.\");\n            }\n            if (Boolean.parseBoolean(allRequestParams.get(\"timersOnly\"))) {\n                query.timers();\n            }\n        }\n        if (allRequestParams.containsKey(\"messagesOnly\") && Boolean.parseBoolean(allRequestParams.get(\"messagesOnly\"))) {\n            query.messages();\n        }\n        if (allRequestParams.containsKey(\"dueBefore\")) {\n            query.duedateLowerThan(RequestUtil.getDate(allRequestParams, \"dueBefore\"));\n        }\n        if (allRequestParams.containsKey(\"dueAfter\")) {\n            query.duedateHigherThan(RequestUtil.getDate(allRequestParams, \"dueAfter\"));\n        }\n        if (allRequestParams.containsKey(\"withException\") && Boolean.parseBoolean(allRequestParams.get(\"withException\"))) {\n            query.withException();\n        }\n        if (allRequestParams.containsKey(\"exceptionMessage\")) {","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/management/JobCollectionResource.java#L124-L160","documentation":"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.","triggerScenarios":"GET /management/jobs?timersOnly=true&messagesOnly=true (both request parameters present at once).","commonSituations":"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.","solutions":["Send only one of the two parameters in a single request.","To get both timer and message jobs, issue two queries and merge results client-side.","Omit both parameters to fetch all job types (or use handlerTypes for finer control).","Fix any client code that blindly serializes both query params."],"exampleFix":"// before\nGET /management/jobs?timersOnly=true&messagesOnly=true\n// after\nGET /management/jobs?timersOnly=true\n// (separate call for messages)\nGET /management/jobs?messagesOnly=true","handlingStrategy":"validation","validationCode":"const params = new URLSearchParams();\nif (timersOnly && messagesOnly) throw new Error('timersOnly and messagesOnly are mutually exclusive');\nif (timersOnly) params.set('timersOnly', 'true');\nif (messagesOnly) params.set('messagesOnly', 'true');","typeGuard":null,"tryCatchPattern":"try {\n  return await listJobs(params);\n} catch (e) {\n  if (e.status === 400 && /timersOnly|messagesOnly/.test(e.message)) {\n    const [a, b] = await Promise.all([listJobs({timersOnly:true}), listJobs({messagesOnly:true})]);\n    return [...a, ...b];\n  }\n  throw e;\n}","preventionTips":["Build query strings from explicit user choices, never append all known flags.","Validate filter inputs client-side before calling the API.","Prefer handlerTypes filtering for combined queries."],"tags":["rest-api","query-parameters","validation","jobs"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}