prestodb/presto · error · PrestoException

INVALID_FUNCTION_ARGUMENT

INVALID_FUNCTION_ARGUMENT

Error message

Illegal replacement sequence: ${replacement.toStringUtf8()}

What it means

Thrown by appendReplacement while rewriting regexp_replace output: the replacement string contains a '$' followed by a group reference or ${name} sequence that is not legal (unknown group name or malformed reference). The offending input is the replacement argument of regexp_replace, not the source string.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/scalar/JoniRegexpFunctions.java:138

        return sliceOutput.slice();
    }

    private static void appendReplacement(SliceOutput result, Slice source, Regex pattern, Region region, Slice replacement)
    {
        // Handle the following items:
        // 1. ${name};
        // 2. $0, $1, $123 (group 123, if exists; or group 12, if exists; or group 1);
        // 3. \\, \$, \t (literal 't').
        // 4. Anything that doesn't starts with \ or $ is considered regular bytes

        int idx = 0;

        while (idx < replacement.length()) {
            byte nextByte = replacement.getByte(idx);
            if (nextByte == '$') {
                idx++;
                if (idx == replacement.length()) { // not using checkArgument because `.toStringUtf8` is expensive
                    throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Illegal replacement sequence: " + replacement.toStringUtf8());
                }
                nextByte = replacement.getByte(idx);
                int backref;
                if (nextByte == '{') { // case 1 in the above comment
                    idx++;
                    int startCursor = idx;
                    while (idx < replacement.length()) {
                        nextByte = replacement.getByte(idx);
                        if (nextByte == '}') {
                            break;
                        }
                        idx++;
                    }
                    byte[] groupName = replacement.getBytes(startCursor, idx - startCursor);
                    try {
                        backref = pattern.nameToBackrefNumber(groupName, 0, groupName.length, region);
                    }
                    catch (ValueException e) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Escape literal dollar signs in the replacement as \$ (or \\$ in SQL string literals)
  2. Reference only capture groups that exist in the pattern, e.g. $1 for (a)b
  3. Use numbered groups $0..$n instead of ${name} unless names are defined
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/scalar/JoniRegexpFunctions.java:138 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/ce94bae5889df722. Report an issue: GitHub.