{"record":{"id":"66163b7e367c62d4","repo":"flowable/flowable-engine","slug":"cannot-combine-onlytimers-with-onlymessages-in-66163b","errorCode":null,"errorMessage":"Cannot combine onlyTimers() with onlyMessages() in the same query","messagePattern":"Cannot combine onlyTimers\\(\\) with onlyMessages\\(\\) in the same query","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/JobQueryImpl.java","lineNumber":126,"sourceCode":"        return this;\n    }\n\n    @Override\n    public JobQuery withRetriesLeft() {\n        retriesLeft = true;\n        return this;\n    }\n\n    @Override\n    public JobQuery executable() {\n        executable = true;\n        return this;\n    }\n\n    @Override\n    public JobQuery timers() {\n        if (onlyMessages) {\n            throw new ActivitiIllegalArgumentException(\"Cannot combine onlyTimers() with onlyMessages() in the same query\");\n        }\n        this.onlyTimers = true;\n        return this;\n    }\n\n    @Override\n    public JobQuery messages() {\n        if (onlyTimers) {\n            throw new ActivitiIllegalArgumentException(\"Cannot combine onlyTimers() with onlyMessages() in the same query\");\n        }\n        this.onlyMessages = true;\n        return this;\n    }\n\n    @Override\n    public JobQuery duedateHigherThan(Date date) {\n        if (date == null) {\n            throw new ActivitiIllegalArgumentException(\"Provided date is null\");","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/JobQueryImpl.java#L108-L144","documentation":"JobQueryImpl.timers() restricts the query to timer jobs, but onlyMessages() (reached via messages()) restricts it to message jobs; the two are mutually exclusive. The engine throws ActivitiIllegalArgumentException immediately when timers() is called after messages() was already set, because the resulting SQL filter would match no job type consistently.","triggerScenarios":"Calling managementService.createJobQuery().messages().timers() (or with the calls in either order) before executing the query.","commonSituations":"Dynamically composing query filters from user-supplied options where both 'timer' and 'message' booleans are true; copying query-building code that adds both filters 'for completeness'; UI search forms allowing both checkboxes to be checked.","solutions":["Remove one of the two calls; pick onlyTimers() or onlyMessages() depending on which job type you need","If the user wants both job types, drop both filters and query all jobs (or issue two separate queries)","Validate input options before building the query and reject conflicting combinations early"],"exampleFix":"// before\nJobQuery query = managementService.createJobQuery().timers().messages();\n\n// after\nJobQuery query = managementService.createJobQuery();\nif (onlyTimers) {\n    query = query.timers();\n} else if (onlyMessages) {\n    query = query.messages();\n}","handlingStrategy":"validation","validationCode":"if (onlyTimers && onlyMessages) throw new IllegalArgumentException(\"Cannot filter for both timer and message jobs in one query\");","typeGuard":null,"tryCatchPattern":"try {\n    query = query.timers();\n} catch (ActivitiIllegalArgumentException e) {\n    if (!e.getMessage().contains(\"onlyTimers\")) throw e;\n    // handle conflicting filter combination, e.g. split into two queries\n}","preventionTips":["Model job-type filters as an enum (ALL, TIMER, MESSAGE) instead of two booleans","Enforce exclusivity in UI/search forms before the query is built","Track which filters have been applied when composing queries dynamically"],"tags":["mutually-exclusive-options","query-builder","validation"],"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-18T11:17:12.947Z"}