{"record":{"id":"49e32bba797581a8","repo":"prestodb/presto","slug":"invalid-function-argument-49e32b","errorCode":"INVALID_FUNCTION_ARGUMENT","errorMessage":"Illegal replacement sequence: ","messagePattern":"Illegal replacement sequence: ","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/type/Re2JRegexp.java","lineNumber":86,"sourceCode":"        }\n        else {\n            re2jPatternWithoutDotStartPrefix = re2jPattern;\n        }\n    }\n\n    public boolean matches(Slice source)\n    {\n        return re2jPatternWithoutDotStartPrefix.find(source);\n    }\n\n    public Slice replace(Slice source, Slice replacement)\n    {\n        Matcher matcher = re2jPattern.matcher(source);\n        try {\n            return matcher.replaceAll(replacement);\n        }\n        catch (IndexOutOfBoundsException | IllegalArgumentException e) {\n            throw new PrestoException(INVALID_FUNCTION_ARGUMENT, \"Illegal replacement sequence: \" + replacement.toStringUtf8());\n        }\n    }\n\n    public Block extractAll(Slice source, long groupIndex)\n    {\n        Matcher matcher = re2jPattern.matcher(source);\n        int group = toIntExact(groupIndex);\n        validateGroup(group, matcher.groupCount());\n\n        BlockBuilder blockBuilder = VARCHAR.createBlockBuilder(null, 32);\n        while (true) {\n            if (!matcher.find()) {\n                break;\n            }\n\n            Slice searchedGroup = matcher.group(group);\n            if (searchedGroup == null) {\n                blockBuilder.appendNull();","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/type/Re2JRegexp.java#L68-L104","documentation":"regexp_replace wraps RE2/J's Matcher.replaceAll, which throws IllegalArgumentException or IndexOutOfBoundsException when the replacement string uses invalid group references or illegal escape/backreference sequences (e.g., a lone '$' or '$9' when fewer groups exist). Re2JRegexp translates that into an INVALID_FUNCTION_ARGUMENT PrestoException naming the offending replacement string.","triggerScenarios":"Calling regexp_replace(pattern, source, replacement) where the replacement Slice contains an invalid group reference (e.g., '$' followed by a digit beyond the group count, unescaped '$', or malformed \\ escape) that RE2/J rejects at replace time.","commonSituations":"Dollar signs in literal replacement text that must be escaped as '$$'; copy-pasted regexes from Java/PCRE engines with group indices larger than the pattern defines; dynamic replacements built from user input.","solutions":["Escape literal '$' in the replacement as '$$' and literal backslashes as '\\\\'.","Ensure every $n reference is <= the number of capture groups in the pattern (count your parentheses).","If the replacement is user-supplied, sanitize it (e.g., Matcher.quoteReplacement semantics) before passing it to regexp_replace."],"exampleFix":"// before\nregexp_replace(name, '(\\w+) (\\w+)', '$1$3')\n// after\nregexp_replace(name, '(\\w+) (\\w+)', '$2 $1')","handlingStrategy":"validation","validationCode":"// Java-side sanity check before building the replacement\nstatic String safeReplacement(String repl) {\n    // escape literal $ and \\ so RE2/J treats them as literals\n    return repl.replace(\"\\\\\", \"\\\\\\\\\").replace(\"$\", \"$$\");\n}","typeGuard":"boolean hasValidGroupRefs(String replacement, int groupCount) {\n    java.util.regex.Matcher m = java.util.regex.Pattern.compile(\"\\\\$(\\\\d+)\").matcher(replacement);\n    while (m.find()) {\n        if (Integer.parseInt(m.group(1)) > groupCount) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    return regexpReplace(pattern, source, replacement);\n} catch (PrestoException e) {\n    if (INVALID_FUNCTION_ARGUMENT.equals(e.getErrorCode()) && e.getMessage().startsWith(\"Illegal replacement sequence\")) {\n        return regexpReplace(pattern, source, escapedReplacement);\n    }\n    throw e;\n}","preventionTips":["Escape '$' as '$$' and '\\' as '\\\\' whenever replacement text can contain literals.","Verify each $n backreference is within the pattern's capture-group count.","Sanitize user-supplied replacement strings before passing them into regexp_replace."],"tags":["presto","regex","re2j","invalid-argument","regexp-replace"],"backgroundTag":"invalid-regex-replacement","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}