OtterMind/Chat2DB · error · IllegalArgumentException

Invalid MySQL {what}: {value}

Error message

Invalid MySQL {what}: {value}

What it means

Thrown by MysqlSqlGuards.requireMysqlName when a value bound into a non-escapable DDL position (ENGINE, CHARACTER SET, COLLATE-style names) fails ^[A-Za-z0-9_]+$. In these positions MySQL does not allow backtick-quoting, so the value is interpolated raw; the guard prevents SQL injection and syntax errors by allowing only plain identifier characters. Null is also rejected.

Source

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

    private static final String DEFINER_SINGLE_QUOTED_PART = "'(?:''|[^'\\\\])+'";
    private static final String DEFINER_BACKTICK_QUOTED_PART = "`(?:``|[^`\\\\])+`";
    private static final String DEFINER_QUOTED_PART = "(?:" + DEFINER_SINGLE_QUOTED_PART + "|"
            + DEFINER_BACKTICK_QUOTED_PART + ")";
    private static final Pattern DEFINER_PATTERN = Pattern.compile(
            "^([A-Za-z0-9_$]+|" + DEFINER_QUOTED_PART + ")@([A-Za-z0-9_.%:$-]+|" + DEFINER_QUOTED_PART + ")$");
    private static final Pattern COLUMN_TYPE_PATTERN = Pattern.compile(
            "^[A-Za-z][A-Za-z0-9_]*(?:\\s*\\(\\s*\\d+(?:\\s*,\\s*\\d+)?\\s*\\))?(?:\\s+[A-Za-z][A-Za-z0-9_]*)*$");

    private MysqlSqlGuards() {
    }

    /**
     * Validate a strict MySQL name token (ENGINE / CHARACTER SET / COLLATE style positions where
     * escaping is impossible by design).
     */
    public static String requireMysqlName(String value, String what) {
        if (value == null || !MYSQL_NAME_PATTERN.matcher(value).matches()) {
            throw new IllegalArgumentException("Invalid MySQL " + what + ": " + value);
        }
        return value;
    }

    /**
     * Validate a raw DEFAULT literal for numeric-ish columns (positions where quoting would change
     * semantics). Accepts decimal/scientific numbers, hex and bit literals, TRUE/FALSE.
     */
    public static String requireNumericDefault(String value) {
        if (value == null || !NUMERIC_DEFAULT_PATTERN.matcher(value.trim()).matches()) {
            throw new IllegalArgumentException("Invalid MySQL default value: " + value);
        }
        return value;
    }

    /**
     * Validate content of a b'...' bit literal.
     */

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Trim the value and confirm it matches ^[A-Za-z0-9_]+$ before passing it to the builder.
  2. Source charset/engine/collation names from a fixed allowlist (e.g. the server's supported list) rather than free text.
  3. If a hyphen or dot legitimately appears, it is not a valid token for this position; reject it upstream.
  4. Never pass user-typed raw strings into ENGINE=/CHARACTER SET=/COLLATE= without allowlist validation.

Example fix

// before
String collation = request.getCollation();
MysqlSqlGuards.requireMysqlName(collation, "collation");

// after
String collation = StringUtils.trimToNull(request.getCollation());
if (collation == null || !collation.matches("^[A-Za-z0-9_]+$")) {
    throw new IllegalArgumentException("Invalid MySQL collation: " + collation);
}
MysqlSqlGuards.requireMysqlName(collation, "collation");
Defensive patterns

Strategy: validation

Validate before calling

String v = StringUtils.trimToNull(value);
if (v == null || !v.matches("^[A-Za-z0-9_]+$")) {
    throw new IllegalArgumentException("Invalid MySQL " + what + ": " + value);
}
MysqlSqlGuards.requireMysqlName(v, what);

Type guard

static boolean isValidMysqlName(String value) {
    return value != null && value.matches("^[A-Za-z0-9_]+$");
}

Prevention

When it happens

Trigger: Calling requireMysqlName(value, what) (directly or via a DDL builder that emits ENGINE=/CHARACTER SET=/COLLATE=) with a value containing a dash, dot, space, or any non-[A-Za-z0-9_] character, or null.

Common situations: A user picks a charset/collation whose name contains an unexpected character; a value is copied from external text with trailing whitespace; an attacker-controlled or untrusted name reaches the builder; 'utf8mb4_0900_ai_ci' style collation names are actually fine (underscore allowed) but a hyphenated or localized name is not.

Related errors


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