{"record":{"id":"a4981f5ef6e7acdf","repo":"oxc-project/oxc","slug":"unexpected-constant-lhs-name-on-the-left-hand-si","errorCode":null,"errorMessage":"Unexpected constant {lhs_name} on the left-hand side of a {expr_name:?} expression","messagePattern":"Unexpected constant (.+?) on the left-hand side of a (.+?) expression","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs","lineNumber":82,"sourceCode":"    /// // However, this will always result in `isEmpty` being `false`.\n    /// ```\n    ///\n    /// Examples of **correct** code for this rule:\n    /// ```javascript\n    /// const x = a + (b ?? c);\n    ///\n    /// const isEmpty = x.length === 0;\n    /// ```\n    NoConstantBinaryExpression,\n    eslint,\n    correctness,\n    config = NoConstantBinaryExpressionConfig,\n    version = \"0.0.3\",\n    short_description = \"Disallow expressions where the operation doesn't affect the value.\",\n);\n\nfn constant_short_circuit(lhs_name: &str, expr_name: &str, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\n        \"Unexpected constant {lhs_name} on the left-hand side of a {expr_name:?} expression\"\n    ))\n    .with_help(\"This expression always evaluates to the constant on the left-hand side\")\n    .with_label(span)\n}\n\nfn constant_binary_operand(left_or_right: &str, operator: &str, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected constant binary expression\")\n        .with_help(format!(\n            \"This compares constantly with the {left_or_right}-hand side of the {operator}\"\n        ))\n        .with_label(span)\n}\n\nfn constant_always_new(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected comparison to newly constructed object\")\n        .with_help(\"These two values can never be equal\")\n        .with_label(span)","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs#L64-L100","documentation":"Diagnostic from the oxlint rule `no-constant-binary-expression`, emitted by `constant_short_circuit` (crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs:81). It fires on `||`/`&&` whose left side has constant truthiness, or on `??` whose left side has constant nullishness — e.g. `true || x`, `[] && foo`, `1 ?? foo`. Because the left operand is statically known, the expression always evaluates to the left constant and the right side is dead. Common trigger: misjudged precedence like `a + b ?? c`, which parses as `(a + b) ?? c` where `a + b` can never be nullish.","triggerScenarios":"AstKind::LogicalExpression where operator is Or/And and `left.is_constant(true, ctx)` (literals, `[]`, `{}`, arrow/function/class expressions, regex literals, boxed `new Boolean(...)`, void/typeof results, template literals without holes), or operator is Coalesce and the left side has constant nullishness (never-nullish objects or always-nullish `undefined`). Message reads e.g. 'Unexpected constant truthiness on the left-hand side of a \"||\" expression'.","commonSituations":"Arithmetic-then-default chains (`price + tax ?? 0`) where the author expected `+` to bind tighter than `??`; developers from value-comparison languages writing `[] && foo`; copy-pasted defaults after a truthiness refactor.","solutions":["Add explicit parentheses to express the intended grouping: `a + (b ?? c)`.","Drop the dead right side entirely when the left is intentionally constant.","For default values use `??` directly on the nullable operand, not on a sub-expression that cannot be nullish.","Replace object-truthiness checks with the specific test you mean, e.g. `x.length === 0` instead of `x === []` patterns."],"exampleFix":"// before\nconst x = a + b ?? c;\n\n// after\nconst x = a + (b ?? c);","handlingStrategy":"validation","validationCode":"// Grep gate for precedence-prone `+ ... ??` and constant-left logicals\nconst precedenceRisk = /[+\\-*/%]\\s*\\w+\\s*\\?\\?/.test(src);\nconst constantLeft = /(^|[([{;,])\\s*(true|false|\\[\\]|\\{\\}|\\d+)\\s*(&&|\\|\\||\\?\\?)/.test(src);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Parenthesize any expression mixing arithmetic and ?? / || / &&.","Never put a literal or fresh object/array on the left of &&, ||, ??.","Keep no-constant-binary-expression enabled in the correctness category."],"tags":["lint","dead-code","operator-precedence","logical-expression","oxlint"],"backgroundTag":"constant-binary-expression","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}