prestodb/presto · error · PrestoException

INVALID_FUNCTION_ARGUMENT

INVALID_FUNCTION_ARGUMENT

Error message

Not a valid Unicode code point: 

What it means

chr(bigint) converts a Unicode code point into its UTF-8 single-character string. The value must be a valid Unicode code point; values outside the allowed ranges (negative, above 0x10FFFF, or the surrogate range 0xD800–0xDFFF) are rejected by SliceUtf8.codePointToUtf8 and rethrown as INVALID_FUNCTION_ARGUMENT.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/scalar/StringFunctions.java:75

/**
 * Current implementation is based on code points from Unicode and does ignore grapheme cluster boundaries.
 * Therefore only some methods work correctly with grapheme cluster boundaries.
 */
public final class StringFunctions
{
    private StringFunctions() {}

    @Description("convert Unicode code point to a string")
    @ScalarFunction
    @SqlType("varchar(1)")
    public static Slice chr(@SqlType(StandardTypes.BIGINT) long codepoint)
    {
        try {
            return SliceUtf8.codePointToUtf8(Ints.saturatedCast(codepoint));
        }
        catch (InvalidCodePointException e) {
            throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Not a valid Unicode code point: " + codepoint, e);
        }
    }

    @Description("returns Unicode code point of a single character string")
    @ScalarFunction("codepoint")
    @SqlType(StandardTypes.INTEGER)
    public static long codepoint(@SqlType("varchar(1)") Slice slice)
    {
        checkCondition(countCodePoints(slice) == 1, INVALID_FUNCTION_ARGUMENT, "Input string must be a single character string");

        return getCodePointAt(slice, 0);
    }

    @Description("count of code points of the given string")
    @ScalarFunction
    @LiteralParameters("x")
    @SqlType(StandardTypes.BIGINT)
    public static long length(@SqlType("varchar(x)") Slice slice)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Clamp or validate the argument to the range 0–1114111 before calling chr.
  2. Skip the surrogate range 55296–57343 or use the actual combined code point for the character.
  3. If you meant to decode bytes, use from_utf8(varbinary) instead of chr per byte.

Example fix

// before
SELECT chr(1114112); -- throws: not a valid Unicode code point
// after
SELECT chr(1114111); -- U+10FFFF, the maximum valid code point
Defensive patterns

Strategy: validation

Validate before calling

-- guard clause before chr(n)
WHERE n BETWEEN 0 AND 1114111 AND (n < 55296 OR n > 57343)

Type guard

// Java
boolean isValidCodePoint(long n) {
    return n >= 0 && n <= 0x10FFFF && !(n >= 0xD800 && n <= 0xDFFF);
}

Prevention

When it happens

Trigger: Calling chr(n) where n < 0, n > 0x10FFFF (1114111), or n is a surrogate code point (55296–57343); also implicitly via Ints.saturatedCast for huge BIGINT values, though saturation clamps those into the invalid negative/large range.

Common situations: Generating characters from byte values > 0x10FFFF, passing raw decimal data meant to be UTF-8 bytes rather than code points, off-by-one using 0x110000 as 'max + 1', generating surrogate halves of an emoji instead of the combined code point.

Related errors


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