apache/seatunnel · error · java.lang.IllegalArgumentException

Can't find column ${col} in table.

Error message

Can't find column ${col} in table.

What it means

getCreateTableStatement fills a user-provided DDL template by substituting column definitions from the SeaTunnel catalog table; mergeColumnInTemplate throws IllegalArgumentException when a placeholder column name from the template cannot be matched to any column of the actual table.

Source

Thrown at seatunnel-connectors-v2/connector-maxcompute/src/main/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/catalog/MaxComputeCatalogUtil.java:152

            if (StringUtils.isEmpty(columnInfo.getInfo())) {
                if (columnMap.containsKey(col)) {
                    Column column = columnMap.get(col);
                    String newCol =
                            columnToMaxComputeType(column, MaxComputeTypeConverter.INSTANCE);
                    String prefix = template.substring(0, columnInfo.getStartIndex() + offset);
                    String suffix = template.substring(offset + columnInfo.getEndIndex());
                    if (prefix.endsWith("`")) {
                        prefix = prefix.substring(0, prefix.length() - 1);
                        offset--;
                    }
                    if (suffix.startsWith("`")) {
                        suffix = suffix.substring(1);
                        offset--;
                    }
                    template = prefix + newCol + suffix;
                    offset += newCol.length() - columnInfo.getName().length();
                } else {
                    throw new IllegalArgumentException("Can't find column " + col + " in table.");
                }
            }
        }
        return template;
    }

    public static String columnToMaxComputeType(
            Column column, TypeConverter<BasicTypeDefine<TypeInfo>> typeConverter) {
        checkNotNull(column, "The column is required.");
        String columnType;
        if (column.getSinkType() != null) {
            columnType = column.getSinkType();
        } else {
            columnType = typeConverter.reconvert(column).getColumnType();
        }
        return String.format(
                "`%s` %s %s %s",
                column.getName(),

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Align the template's column placeholders with the actual SeaTunnel schema field names
  2. Remove stale column placeholders from save_mode_create_template or regenerate it from the current schema
  3. Check field name casing matches exactly between template and source schema

Example fix

// before
String template = "CREATE TABLE ${table} (id BIGINT, old_col STRING)"; // old_col no longer exists
// after
String template = "CREATE TABLE ${table} (id BIGINT, name STRING)";   // matches current schema
Defensive patterns

Strategy: validation

Validate before calling

Set<String> schemaCols = Arrays.stream(rowType.getFieldNames()).collect(Collectors.toSet());
for (String col : templateCols) {
    if (!schemaCols.contains(col)) throw new IllegalArgumentException("template col missing in schema: " + col);
}

Prevention

When it happens

Trigger: save_mode_create_template references a column name that does not exist in the SeaTunnel catalog table being created (typo, renamed field, schema drift between template and source).

Common situations: Hand-written DDL templates copied from an older table schema; source schema changed upstream so a template column vanished; case-sensitivity mismatch between template column and SeaTunnel field names.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/5422dc3ea63264aa. Report an issue: GitHub.