karatelabs/karate · error · TypeError

String.prototype.replaceAll called with a non-global RegExp…

Error message

String.prototype.replaceAll called with a non-global RegExp argument

What it means

This TypeError is thrown by String.prototype.replaceAll when the search value is a RegExp without the global ('g') flag. Per the spec, replaceAll only makes sense for patterns that match everywhere; a non-global regex could match at most once, which contradicts the method's contract, so the engine rejects it.

Solutions

  1. Add the g flag: /foo/g instead of /foo/
  2. Use String.replace if single replacement is intended
  3. Assert rgx.flags.includes('g') or rgx.global before passing to replaceAll

Example fix

// before
s.replaceAll(/foo/, 'bar'); // TypeError
// after
s.replaceAll(/foo/g, 'bar');
Defensive patterns

Strategy: type-guard

Validate before calling

const assertGlobalRegex = (r) => { if (r instanceof RegExp && !r.global) throw new TypeError('replaceAll requires /g'); };

Type guard

const isGlobalRegex = (r) => r instanceof RegExp && r.global;

Try / catch

try { return s.replaceAll(rgx, rep); } catch (e) { if (e instanceof TypeError && !rgx.global) return s.replace(rgx, rep); throw e; }

Prevention

When it happens

Trigger: Calling str.replaceAll(/pattern/, repl) where the regex literal or JsRegex lacks the 'g' flag, e.g. str.replaceAll(/foo/, 'bar'). String.replace accepts non-global regexes; replaceAll does not.

Common situations: Mechanical find-and-replace of .replace( to .replaceAll( without adding the g flag; regexes defined once and reused for both single-match tests and replaceAll; porting code from engines with laxer replaceAll.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/6a4e44f06962f9d7. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsStringPrototype.java:500

        }
        String searchStr = argString(args, 0, context);
        if (replacement instanceof JsCallable fn) {
            int idx = s.indexOf(searchStr);
            if (idx < 0) return s;
            Object r = fn.call(context, new Object[]{searchStr, idx, s});
            String coerced = Terms.toStringCoerce(r, context instanceof CoreContext cc ? cc : null);
            return s.substring(0, idx) + coerced + s.substring(idx + searchStr.length());
        }
        return s.replace(searchStr, argString(args, 1, context));
    }

    private Object replaceAll(Context context, Object[] args) {
        String s = thisString(context, "replaceAll");
        Object search = args.length > 0 ? args[0] : Terms.UNDEFINED;
        Object replacement = args.length > 1 ? args[1] : Terms.UNDEFINED;
        if (search instanceof JsRegex regex) {
            if (!regex.global) {
                throw JsErrorException.typeError("String.prototype.replaceAll called with a non-global RegExp argument");
            }
            if (replacement instanceof JsCallable fn) {
                return regexReplace(s, regex, fn, context, true);
            }
            return regex.replace(s, argString(args, 1, context));
        }
        String searchStr = argString(args, 0, context);
        if (replacement instanceof JsCallable fn) {
            // Walk every literal occurrence; coerce each callback result to string.
            StringBuilder sb = new StringBuilder();
            int from = 0;
            while (true) {
                int idx = searchStr.isEmpty() ? from : s.indexOf(searchStr, from);
                if (idx < 0 || (searchStr.isEmpty() && from > s.length())) break;
                sb.append(s, from, idx);
                Object r = fn.call(context, new Object[]{searchStr, idx, s});
                sb.append(Terms.toStringCoerce(r, context instanceof CoreContext cc ? cc : null));
                if (searchStr.isEmpty()) {

View on GitHub (pinned to a22eb90246)