oxc-project/oxc · error
Read-only global '{global_name}' should not be modified.
Error message
Read-only global '{global_name}' should not be modified. What it means
Diagnostic from oxlint's no-global-assign rule (ESLint port, eslint:recommended). It fires when an assignment writes to a read-only global: a built-in like undefined, NaN, or Infinity, or any variable your lint globals config marks readonly. Such writes throw a TypeError in strict mode or silently no-op in sloppy mode, so the rule stops them statically. The rule config accepts a list of global names to exclude.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_global_assign.rs:15
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_str::CompactStr;
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
config::GlobalValue,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
fn no_global_assign_diagnostic(global_name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Read-only global '{global_name}' should not be modified."))
.with_help(format!("Use a local variable instead of modifying the global '{global_name}'."))
.with_label(span.label(format!("Read-only global '{global_name}' should not be modified.")))
}
#[derive(Debug, Default, Clone, Deserialize)]
pub struct NoGlobalAssign(Box<NoGlobalAssignConfig>);
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoGlobalAssignConfig {
/// List of global variable names to exclude from this rule.
/// Globals listed here can be assigned to without triggering warnings.
exceptions: Vec<CompactStr>,
}
impl std::ops::Deref for NoGlobalAssign {
type Target = NoGlobalAssignConfig;
View on GitHub (pinned to e1e7af627c)
Solutions
- Use a fresh local variable instead of writing to the global.
- If the global genuinely should be writable in your environment, declare it writable in the lint globals config.
- Add the name to this rule's exceptions list in .oxlintrc.json.
- Delete pre-ES5 undefined guards; the property is non-writable in modern engines.
Example fix
// before undefined = null; // silent no-op, TypeError in modules // after const missing = null;
Defensive patterns
Strategy: validation
Validate before calling
const readonlyWrite = /\b(?:undefined|NaN|Infinity)\s*=[^=]/.test(source);
Prevention
- Never assign to built-in globals such as undefined, NaN, and Infinity.
- Keep the globals section of the lint config accurate per environment (browser/node).
- Scope polyfill-style writes to files where the name is marked writable.
When it happens
Trigger: undefined = 5; or NaN = NaN + 1;; writing to a global declared readonly in the globals section of .oxlintrc.json; assigning to built-ins like Infinity inside math helpers.
Common situations: Legacy browser scripts using undefined as a storable variable; pre-ES5 copied code that 'guarded' undefined; shared lint configs marking environment globals readonly, causing false positives in files that legitimately shadow them.
Related errors
- Unexpected assignment to read-only global variable.
- Empty array binding pattern
- Empty object binding pattern
- Redundant Boolean call
- This label '{label_name}' is unnecessary
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/4588c5a09592b097.
Report an issue: GitHub.