{"record":{"id":"e5906016a38d4708","repo":"flowable/flowable-engine","slug":"the-query-is-already-in-an-or-statement-e59060","errorCode":null,"errorMessage":"the query is already in an or statement","messagePattern":"the query is already in an or statement","errorType":"validation","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/HistoryJobQueryImpl.java","lineNumber":227,"sourceCode":"            this.onlyUnlocked = true;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoryJobQuery withoutScopeType() {\n        if (inOrStatement) {\n            this.currentOrQueryObject.withoutScopeType = true;\n        } else {\n            this.withoutScopeType = true;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoryJobQuery or() {\n        if (inOrStatement) {\n            throw new FlowableException(\"the query is already in an or statement\");\n        }\n        inOrStatement = true;\n        if (commandContext != null) {\n            currentOrQueryObject = new HistoryJobQueryImpl(commandContext, jobServiceConfiguration);\n        } else {\n            currentOrQueryObject = new HistoryJobQueryImpl(commandExecutor, jobServiceConfiguration);\n        }\n        orQueryObjects.add(currentOrQueryObject);\n        return this;\n    }\n\n    @Override\n    public HistoryJobQuery endOr() {\n        if (!inOrStatement) {\n            throw new FlowableException(\"endOr() can only be called after calling or()\");\n        }\n        inOrStatement = false;\n        currentOrQueryObject = null;","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/HistoryJobQueryImpl.java#L209-L245","documentation":"HistoryJobQuery.or() throws FlowableException when the query is already inside an or() block (inOrStatement == true). Flowable query API only supports one level of or-nesting; calling or() twice without an intervening endOr() is an invalid state, so it fails fast.","triggerScenarios":"Calling query.or()...or() without calling endOr() in between, or building the query in a loop/helper where or() is invoked per filter without tracking the current or-state.","commonSituations":"Composing query filters programmatically where each filter helper calls or(); copying example code that already opened an or block; retry/rebuild logic that re-applies criteria to the same query object that is still in an or statement.","solutions":["Call endOr() before starting another or() block","Restructure so or() is called exactly once, with all OR criteria between or() and endOr()","Track or-state in query-builder code so or() is only invoked when not already in an or statement","If criteria must be combined independently, build separate queries and merge results instead of nested or()"],"exampleFix":"// before\nquery.or().jobId(id1).or().handlerType(type); // second or() throws\n// after\nquery.or().jobId(id1).handlerType(type).endOr();","handlingStrategy":"validation","validationCode":"if (query instanceof AbstractVariableQueryImpl) { /* or-state is internal; guard at builder level */ }\n// track in your builder:\n// boolean inOr = false;\n// assert !inOr : \"or() already active\";","typeGuard":null,"tryCatchPattern":"try {\n    builder.applyOrCriteria(query);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"already in an or statement\")) {\n        throw new IllegalStateException(\"Query builder opened or() twice without endOr()\", e);\n    }\n    throw e;\n}","preventionTips":["Call or()/endOr() exactly once per OR group, wrapping all OR criteria","Have query-builder helpers accept a single boolean 'useOr' rather than calling or() themselves","Never call or() inside a loop without closing the previous block"],"tags":["java","flowable","query-api","or-statement","api-misuse"],"backgroundTag":"invalid-state-transition","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T16:17:23.245Z"}