oxc-project/oxc · warning · OxcDiagnostic

Useless case in switch statement.

Error message

Useless case in switch statement.

What it means

Diagnostic from the oxlint rule `unicorn/no-useless-switch-case` (pedantic category). It fires for each case clause with an empty consequent (only empty statements, lone blocks, or nothing) that sits immediately before the final `default` clause of a `switch`. Control falls through such a case into `default` anyway, so the case label is dead. No autofix is implemented (`pending`); the help suggests removing the case or the default.

Source

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

use oxc_allocator::UnstableAddress;
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

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

fn no_useless_switch_case_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Useless case in switch statement.")
        .with_help("Consider removing this case or removing the `default` case.")
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallows useless `default` cases in `switch` statements.
    ///
    /// ### Why is this bad?
    ///
    /// An empty case before the last `default` case is useless, as the
    /// `default` case will catch it regardless.
    ///
    /// ### Examples

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Delete the empty case labels that fall straight into `default`.
  2. If the case labels exist for documentation, either add a comment plus a `break;` (any statement silences the rule) or remove them.
  3. If the `default` is itself unnecessary, remove `default` instead; the rule then no longer fires.
  4. Disable inline with `oxlint-disable-next-line unicorn/no-useless-switch-case` for intentional fall-through documentation.

Example fix

// before
switch (foo) {
  case 1:
  default:
    handleDefaultCase();
    break;
}

// after
switch (foo) {
  default:
    handleDefaultCase();
    break;
}
Defensive patterns

Strategy: validation

Validate before calling

# detect empty case labels falling into a final default
rg -n --type js -U 'case\s+[^:]+:\s*(?:case\s+[^:]+:\s*)*default\s*:' src/

Prevention

When it happens

Trigger: `switch (foo) { case a: default: handle(); break; }` flags `case a:`; stacked empty cases `case a: case b: default: ...` flag every empty case; empty blocks `case a: { ;; } default:` also count. Requires exactly one `default`, positioned last; `default` in the middle, missing `default`, or any non-empty statement in the case (even just `break;`) prevents the report.

Common situations: Switches grown over time where a case's body was removed but its label stayed, and template-generated switches that always append a default. Appears when the oxlint pedantic category or unicorn plugin is enabled.

Related errors


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