{"record":{"id":"87582a25b1bd2a23","repo":"flowable/flowable-engine","slug":"endor-can-only-be-called-after-calling-or-87582a","errorCode":null,"errorMessage":"endOr() can only be called after calling or()","messagePattern":"endOr\\(\\) can only be called after calling or\\(\\)","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricPlanItemInstanceQueryImpl.java","lineNumber":828,"sourceCode":"    public HistoricPlanItemInstanceQuery or() {\n        if (inOrStatement) {\n            throw new FlowableIllegalArgumentException(\"The query is already in an or statement\");\n        }\n\n        inOrStatement = true;\n        if (commandContext != null) {\n            currentOrQueryObject = new HistoricPlanItemInstanceQueryImpl(commandContext);\n        } else {\n            currentOrQueryObject = new HistoricPlanItemInstanceQueryImpl(commandExecutor);\n        }\n        orQueryObjects.add(currentOrQueryObject);\n        return this;\n    }\n\n    @Override\n    public HistoricPlanItemInstanceQuery endOr() {\n        if (!inOrStatement) {\n            throw new FlowableIllegalArgumentException(\"endOr() can only be called after calling or()\");\n        }\n\n        inOrStatement = false;\n        currentOrQueryObject = null;\n        return this;\n    }\n\n    @Override\n    public long executeCount(CommandContext commandContext) {\n        return CommandContextUtil.getHistoricPlanItemInstanceEntityManager(commandContext).countByCriteria(this);\n    }\n\n    @Override\n    public List<HistoricPlanItemInstance> executeList(CommandContext commandContext) {\n        List<HistoricPlanItemInstance> historicPlanItems;\n        if (includeLocalVariables){\n            historicPlanItems = CommandContextUtil.getHistoricPlanItemInstanceEntityManager(commandContext).findWithVariablesByCriteria(this);\n        } else {","sourceCodeStart":810,"sourceCodeEnd":846,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricPlanItemInstanceQueryImpl.java#L810-L846","documentation":"HistoricPlanItemInstanceQueryImpl.endOr() throws FlowableIllegalArgumentException when called while the query is not inside an or block (inOrStatement is false). endOr() must always be paired with a preceding or() call. The guard keeps the or/endOr pairing state consistent.","triggerScenarios":"Calling endOr() on a query on which or() was never called, or calling endOr() twice (the first call already reset inOrStatement to false).","commonSituations":"Copy-pasted query builders where the or() call was removed but endOr() remained; double invocation in shared query-building helper methods.","solutions":["Ensure or() is called before endOr()","Remove the redundant endOr() call if no OR grouping is needed","Check that endOr() is not invoked twice on the same query","Refactor query-building helpers to only close an OR block that they opened"],"exampleFix":"// before\nquery.planItemInstanceName(\"a\").endOr(); // throws: no or() before\n// after\nquery.planItemInstanceName(\"a\"); // or: query.or()....endOr()","handlingStrategy":"validation","validationCode":"if (orBlockOpen) {\n    query.endOr();\n    orBlockOpen = false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    query.endOr();\n} catch (FlowableIllegalArgumentException e) {\n    // endOr() called without a matching or() — no action needed or fix builder logic\n}","preventionTips":["Only call endOr() when your builder actually opened an or() block","Use a helper that encapsulates or()...endOr() so pairing is guaranteed","Avoid copy-pasting query fragments containing endOr() without their or()"],"tags":["flowable","cmmn","query","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-14T11:17:12.474Z"}