{"record":{"id":"69e5f8277ba425c1","repo":"quarkusio/quarkus","slug":"not-a-binary-operator","errorCode":null,"errorMessage":"Not a binary operator: ","messagePattern":"Not a binary operator: ","errorType":"exception","errorClass":"TemplateException","httpStatus":null,"severity":"error","filePath":"independent-projects/qute/core/src/main/java/io/quarkus/qute/IfSectionHelper.java","lineNumber":492,"sourceCode":"            return precedence;\n        }\n\n        boolean evaluate(Object op1, Object op2) {\n            switch (this) {\n                case EQ:\n                    return equals(op1, op2);\n                case NE:\n                    return !equals(op1, op2);\n                case GE:\n                case GT:\n                case LE:\n                case LT:\n                    return compare(op1, op2);\n                case AND:\n                case OR:\n                    return !isFalsy(op2);\n                default:\n                    throw new TemplateException(\"Not a binary operator: \" + this);\n            }\n        }\n\n        boolean equals(Object op1, Object op2) {\n            if (Objects.equals(op1, op2)) {\n                return true;\n            }\n            if (op1 != null && op2 != null && (op1 instanceof Number || op2 instanceof Number)) {\n                // Both operands are not null and at least one of them is a number\n                return getDecimal(op1).compareTo(getDecimal(op2)) == 0;\n            }\n            return false;\n        }\n\n        @SuppressWarnings({ \"rawtypes\", \"unchecked\" })\n        boolean compare(Object op1, Object op2) {\n            if (op1 == null || op2 == null) {\n                throw new TemplateException(\"Unable to compare null operands [op1=\" + op1 + \", op2=\" + op2 + \"]\");","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/qute/core/src/main/java/io/quarkus/qute/IfSectionHelper.java#L474-L510","documentation":"In IfSectionHelper, the internal BooleanRepresentation switch handles logical binary operators; if the stored operator code is not one of the known operators, evaluate() throws TemplateException(\"Not a binary operator: \" + this). This signals an internal inconsistency: the parser produced an operator the evaluator does not recognize, or the helper state was corrupted.","triggerScenarios":"Reaching the default branch of the operator switch during {#if} evaluation — an unrecognized/comparator operator leaked into the boolean-operator path, typically due to an internal bug, malformed custom operator registration, or version mismatch.","commonSituations":"Custom operator extensions or forks of Qute; template syntax accepted by one Qute version but not the evaluator of another after an upgrade; corrupted cached template state.","solutions":["Verify the template's {#if} expression uses supported operators (&&, ||, comparison) and no stray characters.","Upgrade/align Quarkus and Qute versions so parser and evaluator agree on operator codes.","Report it as a bug if a plain supported expression triggers it — it indicates an internal parser/evaluator mismatch."],"exampleFix":"// before\n{#if a ??? b} // unsupported/misparsed operator\n// after\n{#if a ?: b} // use the supported elvis operator","handlingStrategy":"try-catch","validationCode":"// validate operator syntax ahead of time\nif (!SUPPORTED_OPERATORS.contains(opToken)) {\n    throw new IllegalArgumentException(\"unsupported operator: \" + opToken);\n}","typeGuard":"boolean isKnownBinaryOp(IfSectionHelper.BooleanRepresentation op) {\n    return op == AND || op == OR; // extend per known set\n}","tryCatchPattern":"try {\n    return condition.evaluate(ctx);\n} catch (TemplateException ex) {\n    if (ex.getMessage().startsWith(\"Not a binary operator\")) {\n        throw new IllegalArgumentException(\"Malformed {#if} expression — check template syntax/versions\", ex);\n    }\n    throw ex;\n}","preventionTips":["Keep parser and evaluator versions aligned (same Quarkus/Qute release)","Use documented operators only (&&, ||, ?:, comparisons)","Report occurrences on stock syntax as upstream bugs with the template snippet"],"tags":["qute","if-section","template","internal-state"],"backgroundTag":"unsupported-operator","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}