oxc-project/oxc · warning · OxcDiagnostic

' ' is already defined as a built-in global variable.

Error message

'{name}' is already defined as a built-in global variable.

What it means

The built-in-globals variant of `no-redeclare`. It flags any declaration whose name collides with a built-in ECMAScript global (`GLOBALS_BUILTIN`) or with a global enabled in your oxlint `globals` config, e.g. `let Object = 1;`. The check only runs when `builtinGlobals` is true and the file is NOT an ES module, because module top-level bindings shadow nothing.

Solutions

  1. Rename the local variable so it does not collide with the global name.
  2. Convert the file to an ES module (add import/export or `"type": "module"`) — the builtin check is skipped for modules.
  3. Set `"no-redeclare": ["error", { "builtinGlobals": false }]` in .oxlintrc to match ESLint's default.
  4. Remove the accidentally enabled name from the `globals` section of .oxlintrc.

Example fix

// before (script file)
var Object = { my: 'shim' };

// after
var myObjectShim = { my: 'shim' };
Defensive patterns

Strategy: validation

Validate before calling

// Verify the flag's two preconditions before linting a script file:
// (1) source is NOT a module, (2) name is a built-in global.
const BUILTINS = new Set(Object.getOwnPropertyNames(globalThis));
const src = require('node:fs').readFileSync(file, 'utf8');
const isModule = /^\s*(import|export)\b/m.test(src);
if (!isModule) {
  for (const m of src.matchAll(/(?:var|let|const|function)\s+([A-Za-z_$][\w$]*)/g)) {
    if (BUILTINS.has(m[1]) || /event|self|name|status|top|length/.test(m[1]))
      console.warn(`possible builtin shadow: ${m[1]} at ${m.index}`);
  }
}

Prevention

When it happens

Trigger: A script-typed file (no import/export, plain .js script or `<script>` source type) containing `let Object = 1;`, `var event = e;` while `globals: { "event": "readonly" }` is configured, or TS redeclarations of a builtin-named symbol.

Common situations: Teams migrating from ESLint where `builtinGlobals` defaults to false — oxlint defaults it to true, so identical code suddenly fails; adding `globals` entries to .oxlintrc that collide with local variable names in scripts.

Related errors


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

Appendix: source

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

use schemars::JsonSchema;
use serde::Deserialize;

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

fn no_redeclare_diagnostic(name: &str, decl_span: Span, re_decl_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("'{name}' is already defined."))
        .with_help("Use a different variable name or remove the duplicate declaration.")
        .with_labels([
            decl_span.label(format!("'{name}' is already defined.")),
            re_decl_span.label("It can not be redeclared here."),
        ])
}

fn no_redeclare_as_builtin_in_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("'{name}' is already defined as a built-in global variable."))
        .with_help("Use a different variable name to avoid shadowing the built-in global.")
        .with_label(span)
}

#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoRedeclare {
    /// When set `true`, it flags redeclaring built-in globals (e.g., `let Object = 1;`).
    builtin_globals: bool,
}

impl Default for NoRedeclare {
    fn default() -> Self {
        Self { builtin_globals: true }
    }
}

declare_oxc_lint!(

View on GitHub (pinned to e1e7af627c)