oxc-project/oxc · info · OxcDiagnostic

Unexpected dangling '_' in

Error message

Unexpected dangling '_' in '`{name}`'.

What it means

`no-underscore-dangle` flags identifiers and member expressions with leading or trailing underscores (the "dangling" underscore), e.g. `this._internal`, `name_`. It reports the exact name in the message and suggests the `allow` config. The rule is highly configurable: `allow` (name list), `allowAfterThis`, `allowAfterSuper`, `allowAfterThisConstructor`, `allowInArrayDestructuring` / `allowInObjectDestructuring` (default true), `allowFunctionParams` (default true), `allowInUsingDeclarations`, plus `enforceInClassFields` / `enforceInMethodNames` to require underscores.

Solutions

  1. Rename your own identifier to drop the dangling underscore.
  2. For library members you cannot rename, add the names to `allow` or enable `allowAfterThis` / `allowAfterSuper`.
  3. If the team convention embraces underscore-privates, disable the rule instead of fighting it.

Example fix

// before
class Store {
  _cache = new Map();
  get(key) {
    return this._cache.get(key);
  }
}

// after
class Store {
  #cache = new Map(); // real private field
  get(key) {
    return this.#cache.get(key);
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# CI gate; tune config (allow, allowAfterThis, ...) instead of suppressing case by case
npx oxlint src/ # rules: { "eslint/no-underscore-dangle": ["warn", { "allow": ["_internal"] }] }

Prevention

When it happens

Trigger: Accessing private-by-convention members `obj._foo`, `this._cache`, naming variables `index_` or `_count` — reported unless covered by one of the allow options or listed in `allow`.

Common situations: Calling third-party/library APIs that expose underscore-prefixed methods; teams whose convention actually uses `_` for private fields (then the rule should be off or configured); destructuring `const { _internal } = obj;` after someone disabled the destructuring allowances.

Related errors


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

Appendix: source

Thrown at crates/oxc_linter/src/rules/eslint/no_underscore_dangle.rs:24

    ast::{
        BindingIdentifier, Expression, FunctionType, PrivateFieldExpression, PropertyKey,
        StaticMemberExpression,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::NodeId;
use oxc_span::Span;

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

fn no_underscore_dangle_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Unexpected dangling '_' in '`{name}`'."))
        .with_help(format!("Remove the dangling '_' or add `{name}` to the 'allow' configuration."))
        .with_label(span)
}

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoUnderscoreDangleConfig {
    /// Whether to allow dangling underscores in members of the `super` object.
    allow_after_super: bool,
    /// Whether to allow dangling underscores in members of the `this.constructor` object.
    allow_after_this_constructor: bool,
    /// An array of variable names that are allowed to have dangling underscores.
    allow: Vec<String>,
    /// Whether to allow dangling underscores in members of the `this` object.
    allow_after_this: bool,
    /// Whether to allow dangling underscores in variable names assigned by array destructuring.
    allow_in_array_destructuring: bool,
    /// Whether to allow dangling underscores in variable names assigned by object destructuring.

View on GitHub (pinned to e1e7af627c)