oxc-project/oxc · warning · OxcDiagnostic

Empty fallbacks in spreads are unnecessary

Error message

Empty fallbacks in spreads are unnecessary

What it means

Diagnostic from the oxlint rule `unicorn/no-useless-fallback-in-spread`. It fires when a spread element inside an object literal uses an empty object as fallback: `{ ...(foo || {}) }` or `{ ...(foo ?? {}) }`. Spreading a falsy value into an object literal adds no properties, so the empty fallback is dead code. The rule is in the correctness category with a conditional autofix that rewrites to `...foo`, applied only when the left side is an identifier, object literal, chain, call, or member expression (not `undefined`, `NaN`, or `Infinity`).

Source

Thrown at crates/oxc_linter/src/rules/unicorn/no_useless_fallback_in_spread.rs:10

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

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

fn no_useless_fallback_in_spread_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Empty fallbacks in spreads are unnecessary")
        .with_help("Spreading falsy values in object literals won't add any unexpected properties, so it's unnecessary to add an empty object as fallback.")
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow useless fallback when spreading in object literals.
    ///
    /// ### Why is this bad?
    ///
    /// Spreading [falsy values](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) in object literals won't add any unexpected properties, so it's unnecessary to add an empty object as fallback.
    ///
    /// ### Examples
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Drop the fallback: `{ ...(foo || {}) }` -> `{ ...foo }`.
  2. Apply the rule's autofix when the left side is fixable (identifier, member, or call expression).
  3. If the goal is to supply defaults, use a non-empty fallback object with real keys.
  4. For intentional cases (for example left side `NaN`), add an inline `oxlint-disable-next-line unicorn/no-useless-fallback-in-spread` comment.

Example fix

// before
const object = { ...(foo || {}) };

// after
const object = { ...foo };
Defensive patterns

Strategy: validation

Validate before calling

# detect ...(x || {}) / ...(x ?? {}) in object spreads
rg -n --type js -U '\.\.\.\s*\([^)]*?\s*(?:\|\||\?\?)\s*\{\s*\}' src/

Prevention

When it happens

Trigger: `const object = { ...(foo || {}) }`, `{ ...(foo ?? {}) }`, nested-paren forms `{ ...((( foo )) ?? (( {} ))) }`, and `async () => ({ ...((await foo) || {}) })`. Only `||` and `??` with an empty object literal on the right, only inside object-literal spreads; `[...(foo || [])]` and `{ ...(foo || { not: 'empty' }) }` do not trigger it.

Common situations: Merging props or options objects, e.g. React spread patterns `{...(props || {})}`, and code migrated from older null-guarded styles. Hits projects that enable oxlint's correctness category or the unicorn plugin.

Related errors


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