oxc-project/oxc · warning · OxcDiagnostic

' ' 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.

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.

Appendix: 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)