oxc-project/oxc · warning · OxcDiagnostic

Identifier '#{name}' is restricted.

Error message

Identifier '#{name}' is restricted.

What it means

The private-class-member variant of the `id-denylist` diagnostic. It is produced by `id_denylist_private_diagnostic` (crates/oxc_linter/src/rules/eslint/id_denylist.rs:35) when a private class field or method whose name (without the `#`) matches a configured denylist entry is declared, e.g. `#data`. The message renders the name with the `#` prefix so it is clear the private member, not a public one, is restricted.

Source

Thrown at crates/oxc_linter/src/rules/eslint/id_denylist.rs:35

use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};

use crate::{
    AstNode,
    context::{ContextHost, LintContext},
    rule::{Rule, TupleRuleConfig},
    rules::eslint::id_match::{
        is_dynamic_import_attribute_object_property, is_known_external_global,
        transparent_reference_parent,
    },
};

fn id_denylist_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Identifier '{name}' is restricted.")).with_label(span)
}

fn id_denylist_private_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Identifier '#{name}' is restricted.")).with_label(span)
}

#[derive(Debug, Default, Clone, Deserialize, Serialize)]
pub struct IdDenylist(Box<FxHashSet<String>>);

impl JsonSchema for IdDenylist {
    fn schema_name() -> String {
        "IdDenylist".to_string()
    }

    fn json_schema(r#gen: &mut SchemaGenerator) -> Schema {
        Schema::Object(SchemaObject {
            instance_type: Some(InstanceType::Array.into()),
            array: Some(Box::new(ArrayValidation {
                additional_items: Some(Box::new(r#gen.subschema_for::<String>())),
                unique_items: Some(true),
                ..Default::default()
            })),

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Rename the private member to be specific: `#data` → `#cachedRows`, `#internal` → `#revalidateInternalState`.
  2. If the bare name should only be banned publicly, remove it from the denylist or rename just the public usages and keep the private one out of the list.
  3. Suppress the single declaration with `oxlint-disable-next-line id-denylist` when the private name mirrors an external protocol or spec.

Example fix

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

// after
class Store {
  #rowsById = new Map();
  read(key) { return this.#rowsById.get(key); }
}
Defensive patterns

Strategy: validation

Validate before calling

// Remember the denylist matches the bare name: 'data' bans both `data` and `#data`.
// Validate with: oxlint --rule id-denylist='["data"]' src/

Prevention

When it happens

Trigger: Rule configured with a denylist containing a name such as `"internal"` or `"data"`, plus a class declaring `#data = ...;`, `#internal() {}`, or a private accessor `get #value()`. Note that the matched name is the bare identifier: denylisting `"data"` also bans `#data`.

Common situations: Migrating a class from TypeScript `private` modifiers to native `#private` fields while a denylist rule is active; the denylist was written for public API names and authors did not realize private members with the same name are also covered; shared configs adding common words like `data`/`temp` that collide with internal private fields.

Related errors


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