oxc-project/oxc · error · OxcDiagnostic

Global flag (g) is missing in the regular expression supplie

Error message

Global flag (g) is missing in the regular expression supplied to the `replaceAll` method.

What it means

Oxlint rule `oxc/bad-replace-all-arg` reports `String.prototype.replaceAll` called with a RegExp lacking the global flag. The diagnostic note is explicit: unlike `replace`, `replaceAll` throws `TypeError: String.prototype.replaceAll called with a non-global RegExp argument` when the regex is non-global. Labels point at the `replaceAll` call and the regex; flags are resolved for literals and `new RegExp` pairs.

Source

Thrown at crates/oxc_linter/src/rules/oxc/bad_replace_all_arg.rs:14

use oxc_ast::{AstKind, ast::RegExpFlags};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{
    AstNode,
    ast_util::{is_method_call, resolve_regex_flags},
    context::LintContext,
    rule::Rule,
};

fn bad_replace_all_arg_diagnostic(replace_all_span: Span, regex_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Global flag (g) is missing in the regular expression supplied to the `replaceAll` method.")
        .with_help("To replace all occurrences of a string, use the `replaceAll` method with the global flag (g) in the regular expression.")
        .with_note("Unlike `replace`, `replaceAll` throws a `TypeError` when passed a non-global regular expression instead of replacing only the first match.")
        .with_labels([
            replace_all_span.label("`replaceAll` called here"),
            regex_span.label("RegExp supplied here"),
        ])
}

#[derive(Debug, Default, Clone)]
pub struct BadReplaceAllArg;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// This rule warns when the `replaceAll` method is called with a regular expression that does not have the global flag (g).
    ///
    /// ### Why is this bad?
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add the global flag: `text.replaceAll(/foo/g, 'bar')`
  2. With dynamic construction: `new RegExp(pattern, flags.includes('g') ? flags : flags + 'g')`
  3. If only the first occurrence should be replaced, keep `.replace()` instead of `replaceAll`
  4. Enable `oxc/bad-replace-all-arg` (correctness) in CI

Example fix

// before
text = text.replaceAll(/-/, '_'); // replaces only first, and throws without /g semantics

// after
text = text.replaceAll(/-/g, '_');
Defensive patterns

Strategy: type-guard

Validate before calling

function toGlobalRegExp(re) {
  return re.global ? re : new RegExp(re.source, re.flags + 'g');
}
// validate before calling
text = text.replaceAll(toGlobalRegExp(re), 'replacement');

Type guard

const isGlobalRegExp = (re) => re.flags.includes('g');
// TypeScript: const isGlobalRegExp = (re: RegExp): re is RegExp & { global: true } => re.flags.includes('g');

Try / catch

try {
  text = text.replaceAll(re, 'replacement');
} catch (e) {
  if (e instanceof TypeError && e.message.includes('non-global')) {
    text = text.replaceAll(new RegExp(re.source, re.flags + 'g'), 'replacement');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: `text.replaceAll(/foo/, 'bar')`; `text.replaceAll(new RegExp('a|b'), '-')`; a module-level regex shared with `.replace()`/`.test()` code reused for `replaceAll`.

Common situations: Upgrading a single `replace` call to `replaceAll` without adding g; dynamic flags strings that omit 'g'; replacing only the first occurrence intentionally but choosing the wrong method.

Related errors


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