{"record":{"id":"667aa361f96405e5","repo":"flowable/flowable-engine","slug":"cannot-combine-onlytimers-with-onlyexternalworke-667aa3","errorCode":null,"errorMessage":"Cannot combine onlyTimers() with onlyExternalWorkers() in the same query","messagePattern":"Cannot combine onlyTimers\\(\\) with onlyExternalWorkers\\(\\) in the same query","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/SuspendedJobQueryImpl.java","lineNumber":481,"sourceCode":"            throw new FlowableIllegalArgumentException(\"Cannot combine onlyExternalWorkers() with onlyMessages() in the same query\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.onlyMessages = true;\n        } else {\n            this.onlyMessages = true;\n        }\n        return this;\n    }\n\n    @Override\n    public SuspendedJobQueryImpl externalWorkers() {\n        if (onlyMessages) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyMessages() with onlyExternalWorkers() in the same query\");\n        }\n\n        if (onlyTimers) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyTimers() with onlyExternalWorkers() in the same query\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.onlyExternalWorkers = true;\n        } else {\n            this.onlyExternalWorkers = true;\n        }\n        return this;\n    }\n\n    @Override\n    public SuspendedJobQueryImpl duedateHigherThan(Date date) {\n        if (date == null) {\n            throw new FlowableIllegalArgumentException(\"Provided date is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.duedateHigherThan = date;\n        } else {","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/SuspendedJobQueryImpl.java#L463-L499","documentation":"SuspendedJobQueryImpl.externalWorkers() restricts the query to jobs handled by external workers. The library throws this FlowableIllegalArgumentException because onlyTimers() and onlyExternalWorkers() are mutually exclusive filters: a job cannot simultaneously be a timer job and an external-worker job. Allowing the combination would produce a query that can never match any row.","triggerScenarios":"Calling suspendedJobQuery() then .onlyTimers().externalWorkers() (or the reverse order) on a SuspendedJobQueryImpl, including inside an or() block where currentOrQueryObject.externalWorkers() is invoked after onlyTimers() was set on that same or-object.","commonSituations":"Developers building a 'show me everything pending' query add both timer and external-worker filters thinking they are additive, or copy-paste a query builder chain that already filtered by timers. Also occurs when refactoring from onlyMessages() to externalWorkers() without removing the timer filter.","solutions":["Remove either onlyTimers() or externalWorkers() from the query chain so only one job-type filter remains.","If both timer and external-worker jobs are needed, run two separate queries and merge the results in application code.","Check for filters set inside or() blocks; the flag may have been set on the currentOrQueryObject in an earlier builder call.","If the intent was to exclude timers rather than select them, remove onlyTimers() and use externalWorkers() alone."],"exampleFix":"// before\nSuspendedJobQuery q = jobService.createSuspendedJobQuery().onlyTimers().externalWorkers();\n// after\nSuspendedJobQuery q = jobService.createSuspendedJobQuery().externalWorkers();","handlingStrategy":"validation","validationCode":"// before building\nboolean wantsTimers = /* ... */;\nboolean wantsExternalWorkers = /* ... */;\nif (wantsTimers && wantsExternalWorkers) {\n    throw new IllegalArgumentException(\"Pick either onlyTimers() or externalWorkers(), not both\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    query = jobService.createSuspendedJobQuery().externalWorkers().list();\n} catch (FlowableIllegalArgumentException e) {\n    // fall back to a single-filter query\n    query = jobService.createSuspendedJobQuery().externalWorkers().list();\n}","preventionTips":["Treat job-type filters (onlyMessages, onlyTimers, externalWorkers) as mutually exclusive radio buttons, not additive flags.","Centralize job-query construction in one helper that enforces the constraint.","Track or()-block state when building filters dynamically."],"tags":["flowable","job-query","conflicting-filters","illegal-argument"],"backgroundTag":"conflicting-config-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"}