oxc-project/oxc · warning · OxcDiagnostic

'{name}' is already a global variable.

Error message

'{name}' is already a global variable.

What it means

oxlint's `no-shadow` rule emits this diagnostic (from `no_shadow_global_diagnostic`) when a local binding — var/let/const, function or class declaration, parameter, or catch binding — reuses the name of a JavaScript builtin global such as `name`, `length`, `status`, or `Promise`. The lookup uses the `javascript_globals::GLOBALS` table, so the exact set depends on the configured environment (browser, node, etc.). It is a static-analysis warning: the local binding hides the global inside that scope, so code that appears to reference the global actually references the local.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_shadow/mod.rs:56

            .with_help(format!(
                "Consider renaming '{name}' to avoid shadowing the variable from the outer scope."
            ))
            .with_labels([
                span.label(format!("'{name}' is declared here")),
                shadowed_span.label("shadowed declaration is here"),
            ]);

    if is_enum_member {
        diagnostic.with_note(format!(
            "Enum members are added to the enum scope, so references to '{name}' in enum member initializers resolve to this member instead of the declaration in the upper scope."
        ))
    } else {
        diagnostic
    }
}

pub fn no_shadow_global_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("'{name}' is already a global variable."))
        .with_help(format!("Consider renaming '{name}' to avoid shadowing the global variable."))
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct NoShadow(Box<NoShadowConfig>);

impl std::ops::Deref for NoShadow {
    type Target = NoShadowConfig;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

declare_oxc_lint!(
    /// ### What it does
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Rename the local binding to something specific (e.g. `name` -> `userName`).
  2. If the shadowing is intentional, suppress it inline with `// oxlint-disable-next-line eslint/no-shadow`.
  3. Review the rule's config (HoistOption / NoShadowConfig) to stop reporting hoisted functions before use.
  4. Adjust the `globals` configuration in .oxlintrc.json so env globals you never intend to shadow are the only ones checked.

Example fix

// before
function greet() {
  const name = 'Ada'; // shadows the browser global `name`
  return name;
}

// after
function greet() {
  const userName = 'Ada';
  return userName;
}
Defensive patterns

Strategy: validation

Validate before calling

# CI gate before merge
npx oxlint -c .oxlintrc.json src/ # .oxlintrc.json: { "rules": { "eslint/no-shadow": "warn" } }

Prevention

When it happens

Trigger: Declaring any binding whose name matches an entry in the GLOBALS table for your env: `const name = 'x'` inside a function, `class Promise {}`, a function parameter named `event`, a catch parameter named `length`. The diagnostic fires once per shadowing symbol found while iterating `scoping.symbol_ids()` in the rule's `run_once`.

Common situations: Enabling stricter no-shadow settings (ESLint's `builtinGlobals: true` behavior); browser projects accidentally shadowing `name`, `length`, `status`, `self`, or `event`; porting an ESLint config to oxlint where globals come from the `globals` configuration instead of `env`, suddenly surfacing dozens of hits.

Related errors


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