oxc-project/oxc · warning · OxcDiagnostic

This assigned value is not used in subsequent statements.

Error message

This assigned value is not used in subsequent statements.

What it means

Diagnostic from oxlint's no-useless-assignment rule. It flags a dead store: the value assigned at this span is never read on any subsequent path (overwritten first, or the scope/function exits), built from oxc_semantic reference and scope data (SymbolId/Reference/ScopeId).

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_useless_assignment.rs:26

        AssignmentTarget as AstAssignmentTarget, BindingPattern, Expression,
        VariableDeclarationKind,
    },
};
use oxc_cfg::{
    BasicBlockId, BlockNodeId, ControlFlowGraph, EdgeType, ErrorEdgeKind, Graph,
    graph::{
        Direction,
        visit::{Control, DfsEvent, EdgeRef, depth_first_search},
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_index::IndexVec;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::{NodeId, Reference, ScopeId, SymbolId};
use oxc_span::GetSpan;
use oxc_span::Span;

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

fn no_useless_assignment_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("This assigned value is not used in subsequent statements.")
        .with_help("Consider removing or reusing the assigned value.")
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Flags assignments where the newly assigned value is never read afterward (a "dead store"). This helps catch wasted work or accidental mistakes.
    ///
    /// ### Why is this bad?
    ///
    /// Dead stores add noise and can hide real bugs (e.g., you meant to use that value or wrote to the wrong variable). Removing them improves clarity and performance.

View on GitHub (pinned to 1f902a6962)

Solutions

  1. Remove the never-read assignment.
  2. Reorder so the assignment sits after any exit point and immediately before the first read.
  3. Hoist to const at the point of single use.
  4. If the RHS has side effects, keep the call but make discarding its result explicit.

Example fix

// before
function f(xs) {
  let last;
  for (const x of xs) { last = x; }
  last = xs[0];
  return last;
}
// after
function f(xs) {
  let last;
  for (const x of xs) { last = x; }
  return last;
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: let x = compute(); throw new Error(); where x is never read; x = 1; x = 2; use(x); where the first write is dead; an assignment after the last read inside a branch that then returns.

Common situations: Accumulator variables replaced wholesale; state resets at the end of loop iterations nobody reads; assignments stranded above an early-return guard added later; debug assignments left after final use.

Related errors


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