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
- Trim the value and confirm it matches ^[A-Za-z0-9_]+$ before passing it to the builder.
- Source charset/engine/collation names from a fixed allowlist (e.g. the server's supported list) rather than free text.
- If a hyphen or dot legitimately appears, it is not a valid token for this position; reject it upstream.
- 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
- Source ENGINE/CHARACTER SET/COLLATE names from a server allowlist, not free text.
- Trim whitespace from copy-pasted names.
- Never pass untrusted strings into non-escapable DDL positions.
- Reject hyphenated or dotted names upstream; they are invalid tokens here.
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
- Invalid MySQL definer: {value}
- Invalid MongoDB database name: {name}
- Invalid MySQL default value: {value}
- Invalid MySQL bit literal: {value}
- Invalid MySQL hex digits: {value}
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/a457e78901ee66b8.
Report an issue: GitHub.