{"record":{"id":"467bbacb3f9ca07d","repo":"flowable/flowable-engine","slug":"the-query-is-already-in-an-or-statement-467bba","errorCode":null,"errorMessage":"the query is already in an or statement","messagePattern":"the query is already in an or statement","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/JobQueryImpl.java","lineNumber":563,"sourceCode":"            this.onlyUnlocked = true;\n        }\n        return this;\n    }\n\n    @Override\n    public JobQuery 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 JobQuery 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 JobQueryImpl(commandContext, jobServiceConfiguration);\n        } else {\n            currentOrQueryObject = new JobQueryImpl(commandExecutor, jobServiceConfiguration);\n        }\n        orQueryObjects.add(currentOrQueryObject);\n        return this;\n    }\n\n    @Override\n    public JobQuery endOr() {\n        if (!inOrStatement) {\n            throw new FlowableException(\"endOr() can only be called after calling or()\");\n        }\n        inOrStatement = false;\n        currentOrQueryObject = null;","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/JobQueryImpl.java#L545-L581","documentation":"FlowableException thrown by JobQueryImpl.or() when the query is already inside an or() block. Flowable supports only a single or() segment per query; a second nested or() call has no well-defined semantics, so it is rejected. The fix is to finish the or-block (with endOr()) and start a new query, or merge the conditions inside the existing block.","triggerScenarios":"Calling or() twice without an intervening endOr(); building queries recursively where an inner builder also calls or(); adding a shared 'default filter' helper that calls or() onto a query already in or-mode.","commonSituations":"Composable query-builder frameworks stacking filter fragments each of which opens its own or(); misreading or() as re-entrant like SQL parentheses; tests reusing one query object across multiple filter helpers.","solutions":["Call or() only once per query and place all OR-ed conditions before endOr().","Ensure every or() is paired with endOr() before any further or() call.","Refactor filter helpers to detect or-state (or reuse the current or-query object) instead of always calling or().","If two OR groups are needed, issue two queries and combine results in code."],"exampleFix":"// before\nquery.or().jobTenantId(\"t1\");\nquery.or().handlerType(\"timer\"); // throws: already in or statement\n\n// after\nquery.or()\n    .jobTenantId(\"t1\")\n    .handlerType(\"timer\")\n    .endOr();","handlingStrategy":"validation","validationCode":"if (!queryInOrMode) {\n    query.or();\n    queryInOrMode = true;\n} // always call endOr() before opening another or-block","typeGuard":null,"tryCatchPattern":"try {\n    query.or();\n} catch (org.flowable.common.engine.api.FlowableException e) {\n    if (e.getMessage().contains(\"already in an or statement\")) {\n        query.endOr();\n        query.or();\n    } else {\n        throw e;\n    }\n}","preventionTips":["Pair every or() with exactly one endOr().","Design query-builder helpers to append conditions into the existing or-block instead of opening a new one.","Keep one or-block per query; use multiple queries for multiple OR groups."],"tags":["invalid-state","query","or-statement","flowable"],"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-14T16:17:12.679Z"}