oxc-project/oxc · warning · OxcDiagnostic
'{name}' 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.
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)
Solutions
- Rename the local variable so it does not collide with the global name.
- Convert the file to an ES module (add import/export or `"type": "module"`) — the builtin check is skipped for modules.
- Set `"no-redeclare": ["error", { "builtinGlobals": false }]` in .oxlintrc to match ESLint's default.
- 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
- Set `"builtinGlobals": false` in .oxlintrc when migrating an ESLint config so behavior matches.
- Keep scripts as ES modules (`"type": "module"`) — the builtin-globals half of the rule is skipped for modules.
- Avoid naming locals after DOM/JS globals (`event`, `name`, `self`, `Object`) even when the linter allows it.
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
- Unexpected use of '{global_name}'.
- Read-only global '{global_name}' should not be modified.
- '{name}' is already defined.
- Reexporting 'default' export is restricted.
- Exporting 'default' is restricted.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/00334eeb62d56e6a.
Report an issue: GitHub.