{"record":{"id":"6a4e44f06962f9d7","repo":"karatelabs/karate","slug":"string-prototype-replaceall-called-with-a-non-global-regexp","errorCode":null,"errorMessage":"String.prototype.replaceAll called with a non-global RegExp argument","messagePattern":"String\\.prototype\\.replaceAll called with a non-global RegExp argument","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsStringPrototype.java","lineNumber":500,"sourceCode":"        }\n        String searchStr = argString(args, 0, context);\n        if (replacement instanceof JsCallable fn) {\n            int idx = s.indexOf(searchStr);\n            if (idx < 0) return s;\n            Object r = fn.call(context, new Object[]{searchStr, idx, s});\n            String coerced = Terms.toStringCoerce(r, context instanceof CoreContext cc ? cc : null);\n            return s.substring(0, idx) + coerced + s.substring(idx + searchStr.length());\n        }\n        return s.replace(searchStr, argString(args, 1, context));\n    }\n\n    private Object replaceAll(Context context, Object[] args) {\n        String s = thisString(context, \"replaceAll\");\n        Object search = args.length > 0 ? args[0] : Terms.UNDEFINED;\n        Object replacement = args.length > 1 ? args[1] : Terms.UNDEFINED;\n        if (search instanceof JsRegex regex) {\n            if (!regex.global) {\n                throw JsErrorException.typeError(\"String.prototype.replaceAll called with a non-global RegExp argument\");\n            }\n            if (replacement instanceof JsCallable fn) {\n                return regexReplace(s, regex, fn, context, true);\n            }\n            return regex.replace(s, argString(args, 1, context));\n        }\n        String searchStr = argString(args, 0, context);\n        if (replacement instanceof JsCallable fn) {\n            // Walk every literal occurrence; coerce each callback result to string.\n            StringBuilder sb = new StringBuilder();\n            int from = 0;\n            while (true) {\n                int idx = searchStr.isEmpty() ? from : s.indexOf(searchStr, from);\n                if (idx < 0 || (searchStr.isEmpty() && from > s.length())) break;\n                sb.append(s, from, idx);\n                Object r = fn.call(context, new Object[]{searchStr, idx, s});\n                sb.append(Terms.toStringCoerce(r, context instanceof CoreContext cc ? cc : null));\n                if (searchStr.isEmpty()) {","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsStringPrototype.java#L482-L518","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the g flag: /foo/g instead of /foo/","Use String.replace if single replacement is intended","Assert rgx.flags.includes('g') or rgx.global before passing to replaceAll"],"exampleFix":"// before\ns.replaceAll(/foo/, 'bar'); // TypeError\n// after\ns.replaceAll(/foo/g, 'bar');","handlingStrategy":"type-guard","validationCode":"const assertGlobalRegex = (r) => { if (r instanceof RegExp && !r.global) throw new TypeError('replaceAll requires /g'); };","typeGuard":"const isGlobalRegex = (r) => r instanceof RegExp && r.global;","tryCatchPattern":"try { return s.replaceAll(rgx, rep); } catch (e) { if (e instanceof TypeError && !rgx.global) return s.replace(rgx, rep); throw e; }","preventionTips":["Define regexes intended for replaceAll with the g flag at the call site","When converting .replace( to .replaceAll(, always add g to the pattern","Normalize flags once when regexes are shared across features"],"tags":["javascript","regex","type-error","string"],"backgroundTag":"invalid-argument-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}