OtterMind/Chat2DB · error · IllegalArgumentException

Invalid MySQL hex digits: {value}

Error message

Invalid MySQL hex digits: {value}

What it means

Thrown by MysqlSqlGuards.requireHexDigits when the digits of a 0x... hex literal (without the 0x prefix, which the template adds) fail ^[0-9a-fA-F]+$. Only hexadecimal digits are accepted; null, empty, or non-hex characters are rejected because they would corrupt the literal.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlSqlGuards.java:73

        return value;
    }

    /**
     * Validate content of a b'...' bit literal.
     */
    public static String requireBitLiteral(String value) {
        if (value == null || !BIT_LITERAL_PATTERN.matcher(value).matches()) {
            throw new IllegalArgumentException("Invalid MySQL bit literal: " + value);
        }
        return value;
    }

    /**
     * Validate the digits of a 0x... hex literal (the template adds the 0x prefix).
     */
    public static String requireHexDigits(String value) {
        if (value == null || !HEX_DIGITS_PATTERN.matcher(value).matches()) {
            throw new IllegalArgumentException("Invalid MySQL hex digits: " + value);
        }
        return value;
    }

    /**
     * True only when the value is a well-formed 0x... hex literal. Values that merely
     * start with 0x but contain non-hex characters must not pass through into SQL raw.
     */
    public static boolean isHexLiteral(String value) {
        return value != null && HEX_LITERAL_PATTERN.matcher(value).matches();
    }

    /**
     * Validate a DEFINER value (user@host, parts optionally single-quoted or backtick-quoted).
     */
    public static String requireDefiner(String value) {
        if (value == null || !DEFINER_PATTERN.matcher(value).matches()) {
            throw new IllegalArgumentException("Invalid MySQL definer: " + value);

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Pass only the raw hex digits to requireHexDigits, not the 0x-prefixed form.
  2. Strip a leading 0x/0X and validate the remainder matches ^[0-9a-fA-F]+$ before calling.
  3. Remove dashes/colons from formatted hex (UUIDs) before validation.
  4. Reject empty/null hex values upstream.

Example fix

// before
MysqlSqlGuards.requireHexDigits(rawHex);

// after
String hex = StringUtils.trimToNull(rawHex);
if (hex != null && (hex.startsWith("0x") || hex.startsWith("0X"))) {
    hex = hex.substring(2);
}
if (hex == null || !hex.matches("^[0-9a-fA-F]+$")) {
    throw new IllegalArgumentException("Invalid MySQL hex digits: " + rawHex);
}
MysqlSqlGuards.requireHexDigits(hex);
Defensive patterns

Strategy: validation

Validate before calling

String hex = StringUtils.trimToNull(value);
if (hex != null && (hex.startsWith("0x") || hex.startsWith("0X"))) {
    hex = hex.substring(2);
}
if (hex == null || !hex.matches("^[0-9a-fA-F]+$")) {
    throw new IllegalArgumentException("Invalid MySQL hex digits: " + value);
}
MysqlSqlGuards.requireHexDigits(hex);

Type guard

static boolean isHexDigits(String value) {
    return value != null && value.matches("^[0-9a-fA-F]+$");
}

Prevention

When it happens

Trigger: Calling requireHexDigits(value) with a string containing non-hex characters (g-z, symbols), an empty string, or null. The caller passes only the hex digits, not the full 0x... literal.

Common situations: Passing the full 0x1A2B literal instead of just '1A2B'; a value containing an odd trailing character from copy-paste; a UI hex input that did not strip a leading '0x'; passing a UUID with dashes to a hex literal position.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/884751875b85b6e0. Report an issue: GitHub.