oxc-project/oxc · warning · OxcDiagnostic
'{name}' is defined but never used.
Error message
'{name}' is defined but never used. What it means
Diagnostic from oxlint's no-unused-private-class-members rule. A #private field or method is declared but never referenced as this.#name anywhere, so it is dead code; very often the usage exists but is missing the # prefix (a typo that silently reads a public/undefined property instead).
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_unused_private_class_members.rs:12
use itertools::Itertools;
use oxc_ast::{AstKind, ast::AssignmentOperator};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::{AstNode, NodeId, Semantic};
use oxc_span::{GetSpan, Span};
use oxc_syntax::class::ElementKind;
use crate::{context::LintContext, rule::Rule};
fn no_unused_private_class_members_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("'{name}' is defined but never used."))
.with_help("Remove the declaration or use it in the code.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoUnusedPrivateClassMembers;
declare_oxc_lint!(
/// ### What it does
///
/// Disallow unused private class members.
///
/// ### Why is this bad?
///
/// Private class members that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such class members take up space in the code and can lead to confusion by readers.
///
/// ### Examples
///View on GitHub (pinned to e1e7af627c)
Solutions
- If the member is a typo victim, fix the use sites to include the #: this.#secret.
- Otherwise remove the unused private member entirely.
- Re-add the member only when a real consumer exists, instead of keeping dead state.
Example fix
// before
class C {
#secret = 1;
read() { return this.secret; }
}
// after
class C {
#secret = 1;
read() { return this.#secret; }
} Defensive patterns
Strategy: validation
Prevention
- After renaming a private member, grep for both this.#name and this.name to catch dropped '#' prefixes.
- Delete speculative private fields; add them when a real consumer exists.
- Keep the rule enabled so unused privates surface at lint time rather than review time.
When it happens
Trigger: class C { #secret = 1; read() { return this.secret; } } (forgot the #); a #cache field never touched; renaming a member but not all use sites.
Common situations: Refactor renames where the # is dropped; speculative memoization fields kept 'for later'; privates whose only consumer was removed.
Related errors
- File has too many classes ({total}). Maximum allowed is {max
- Duplicate class member: {member_name:?}
- Redundant Boolean call
- This label '{label_name}' is unnecessary
- Expected to always call `super()` before `this`/`super` prop
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/fdf1a40c2f1ce5fc.
Report an issue: GitHub.