OtterMind/Chat2DB · error · IllegalArgumentException

Invalid MySQL column type: {value}

Error message

Invalid MySQL column type: {value}

What it means

Thrown by MysqlSqlGuards.requireColumnType when a fallback column type expression fails COLUMN_TYPE_PATTERN. The pattern requires the type to start with a letter, allow [A-Za-z0-9_], an optional (precision[,scale]) group, and trailing keyword modifiers (each starting with a letter). It preserves custom type names while rejecting anything containing SQL metacharacters. The value is trimmed first.

Source

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

    /**
     * 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);
        }
        return value;
    }

    /**
     * Validate a fallback column type expression while preserving common custom type names,
     * optional numeric precision/scale and keyword modifiers.
     */
    public static String requireColumnType(String value) {
        String trimmed = StringUtils.trimToEmpty(value);
        if (!COLUMN_TYPE_PATTERN.matcher(trimmed).matches()) {
            throw new IllegalArgumentException("Invalid MySQL column type: " + value);
        }
        return trimmed;
    }

    /**
     * Validate an index sort direction: only ASC/DESC are legal, returned in canonical uppercase.
     */
    public static String requireAscOrDesc(String value) {
        String trimmed = StringUtils.trimToEmpty(value);
        if ("ASC".equalsIgnoreCase(trimmed)) {
            return "ASC";
        }
        if ("DESC".equalsIgnoreCase(trimmed)) {
            return "DESC";
        }
        throw new IllegalArgumentException("Invalid MySQL index sort direction: " + value);
    }

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Trim the type and strip surrounding backticks/quotes before passing to requireColumnType.
  2. Ensure precision/scale inside parentheses are numeric only.
  3. Reject types with embedded SQL metacharacters upstream.
  4. If the type is exotic, confirm it is a real MySQL type name and not an expression.

Example fix

// before
MysqlSqlGuards.requireColumnType(columnType);

// after
String t = StringUtils.trimToEmpty(columnType);
if (!t.matches("^[A-Za-z][A-Za-z0-9_]*(\\s*\\(\\s*\\d+(\\s*,\\s*\\d+)?\\s*\\))?(\\s+[A-Za-z][A-Za-z0-9_]*)*$")) {
    throw new IllegalArgumentException("Invalid MySQL column type: " + columnType);
}
MysqlSqlGuards.requireColumnType(t);
Defensive patterns

Strategy: validation

Validate before calling

String t = StringUtils.trimToEmpty(value);
if (!t.matches("^[A-Za-z][A-Za-z0-9_]*(\\s*\\(\\s*\\d+(\\s*,\\s*\\d+)?\\s*\\))?(\\s+[A-Za-z][A-Za-z0-9_]*)*$")) {
    throw new IllegalArgumentException("Invalid MySQL column type: " + value);
}
MysqlSqlGuards.requireColumnType(t);

Type guard

static boolean isValidColumnType(String value) {
    String t = StringUtils.trimToEmpty(value);
    return t.matches("^[A-Za-z][A-Za-z0-9_]*(\\s*\\(\\s*\\d+(\\s*,\\s*\\d+)?\\s*\\))?(\\s+[A-Za-z][A-Za-z0-9_]*)*$");
}

Prevention

When it happens

Trigger: Calling requireColumnType(value) with a type containing parentheses with non-numeric content, a leading digit or symbol, embedded quotes/backticks, commas outside parentheses, or any char outside [A-Za-z0-9_ ()].

Common situations: A custom column type pasted with surrounding backticks or quotes; a type like 'VARCHAR(255) UNSIGNED' that is fine, versus 'int(10)`x`' that is not; a parameterized type where the precision contains letters; a type string concatenated from untrusted input.

Related errors


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