{"record":{"id":"c9fec14f40fbc9a4","repo":"flowable/flowable-engine","slug":"cannot-combine-onlyexternalworkers-with-onlymess","errorCode":null,"errorMessage":"Cannot combine onlyExternalWorkers() with onlyMessages() in the same query","messagePattern":"Cannot combine onlyExternalWorkers\\(\\) with onlyMessages\\(\\) 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/DeadLetterJobQueryImpl.java","lineNumber":433,"sourceCode":"\n    @Override\n    public DeadLetterJobQueryImpl executable() {\n        if (inOrStatement) {\n            this.currentOrQueryObject.executable = true;\n        } else {\n            this.executable = true;\n        }\n        return this;\n    }\n\n    @Override\n    public DeadLetterJobQueryImpl timers() {\n        if (onlyMessages) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyTimers() with onlyMessages() in the same query\");\n        }\n\n        if (onlyExternalWorkers) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyExternalWorkers() with onlyMessages() in the same query\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.onlyTimers = true;\n        } else {\n            this.onlyTimers = true;\n        }\n        return this;\n    }\n\n    @Override\n    public DeadLetterJobQueryImpl messages() {\n        if (onlyTimers) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyTimers() with onlyMessages() in the same query\");\n        }\n\n        if (onlyExternalWorkers) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyExternalWorkers() with onlyMessages() in the same query\");\n        }","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/DeadLetterJobQueryImpl.java#L415-L451","documentation":"Flowable's DeadLetterJobQueryImpl enforces that a dead-letter job query narrows results to at most one job category. Calling timers() after onlyExternalWorkers() and onlyMessages() flags are already set makes the query contradictory, so FlowableIllegalArgumentException is thrown. This fail-fast validation prevents building an impossible SQL filter.","triggerScenarios":"Calling deadLetterJobQuery().onlyExternalWorkers() ... .messages() ... .timers() (i.e. timers() invoked while the onlyExternalWorkers flag is set). The check fires in timers() when onlyExternalWorkers is true.","commonSituations":"Building a query programmatically by appending category filters from user input or configuration without tracking which category flags were already applied; refactoring code that switched from timers/messages filtering to external-worker filtering while leaving stale calls in the chain.","solutions":["Keep at most one of onlyExternalWorkers(), onlyMessages(), timers() in the query chain","Restructure the code so the category filter is chosen once (if/else) instead of chaining conditionally","If a broader query is needed, build a fresh DeadLetterJobQueryImpl instead of reusing a partially configured one"],"exampleFix":"// before\nmanagementService.createDeadLetterJobQuery().onlyExternalWorkers().messages().timers();\n// after\nmanagementService.createDeadLetterJobQuery().timers(); // pick exactly one category","handlingStrategy":"validation","validationCode":"if (useExternalWorkers && useMessages) { throw new IllegalArgumentException(\"Pick only one of onlyExternalWorkers/messages/timers\"); }","typeGuard":null,"tryCatchPattern":"try { query = mgmt.createDeadLetterJobQuery().timers(); } catch (FlowableIllegalArgumentException e) { log.error(\"Conflicting category filters\", e); }","preventionTips":["Track which category flag was applied in a variable before chaining","Never chain more than one of timers()/messages()/onlyExternalWorkers()","Wrap query building in a builder helper that enforces one category"],"tags":["flowable","job-query","illegal-argument","query-builder"],"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-14T05:17:10.506Z"}