oxc-project/oxc · error · OxcDiagnostic

Unexpected object literal comparison.

Error message

Unexpected object literal comparison.

What it means

Oxlint rule `oxc/bad-object-literal-comparison` fires on an equality comparison (`==`, `===`, `!=`, `!==`) in which one operand is an empty object literal `{}`. Every literal creates a fresh reference, so `x === {}` is always false and `x !== {}` always true; the help text reports that constant result and suggests `Object.entries()`/`Object.keys()` with a length check. The rule only matches empty object literals (the source checks `properties.is_empty()`).

Source

Thrown at crates/oxc_linter/src/rules/oxc/bad_object_literal_comparison.rs:10

use oxc_ast::{AstKind, ast::Expression};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_syntax::operator::BinaryOperator;

use crate::{AstNode, context::LintContext, rule::Rule};

fn object_comparison(span: Span, const_result: bool) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected object literal comparison.")
        .with_help(format!(
            "This comparison will always return {const_result:?} as object literals are never equal to each other. Consider using `Object.entries()` of `Object.keys()` and comparing their lengths."
        ))
        .with_label(span)
}

fn array_comparison(span: Span, const_result: bool) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected array literal comparison.")
        .with_help(format!("This comparison will always return {const_result:?} as array literals are never equal to each other. Consider using `Array.length` if empty checking was intended."))
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct BadObjectLiteralComparison;

declare_oxc_lint!(
    /// ### What it does
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace with an emptiness check: `typeof x === 'object' && x !== null && Object.keys(x).length === 0`
  2. If deep content comparison was intended, use `assert.deepStrictEqual`, `lodash.isEqual`, or a custom deep-equal helper
  3. If identity comparison was intended, compare stable identifiers (e.g. `x.id === y.id`) instead of literals

Example fix

// before
if (x === {}) { /* never runs */ }

// after
if (x !== null && typeof x === 'object' && Object.keys(x).length === 0) { /* runs when empty */ }
Defensive patterns

Strategy: type-guard

Validate before calling

// .oxlintrc.json — catch it before runtime
{
  "rules": { "oxc/bad-object-literal-comparison": "error" }
}

Type guard

function isEmptyObject(v) {
  return typeof v === 'object' && v !== null && !Array.isArray(v) && Object.keys(v).length === 0;
}
if (isEmptyObject(x)) { /* ... */ }

Prevention

When it happens

Trigger: `if (x === {}) {}` (always false); `if (user !== {}) {}` (always true); `if (typeof person != 'object' || person != {}) {}`; any `==`/`===`/`!=`/`!==` comparison with a bare `{}` operand.

Common situations: Developers from Python/C# expecting value equality; attempting to test 'is the object empty'; hastily written default-options guards; comparisons auto-generated from schemas.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/6ba82a6a2d610ec1. Report an issue: GitHub.