OtterMind/Chat2DB · error · IllegalArgumentException
DM index must contain at least one named column
Error message
DM index must contain at least one named column
What it means
Thrown by DMIndexTypeEnum.buildIndexColumn (inside DMIndexTypeEnum) when, after iterating every TableIndexColumn, none had a non-blank columnName. The guard prevents emitting an index DDL fragment with an empty column list "()", which would be invalid SQL.
Source
Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-dm/src/main/java/ai/chat2db/plugin/dm/enums/type/DMIndexTypeEnum.java:109
}
private String buildIndexColumn(TableIndex tableIndex) {
StringBuilder script = new StringBuilder();
script.append("(");
boolean hasColumn = false;
for (TableIndexColumn column : tableIndex.getColumnList()) {
if (StringUtils.isNotBlank(column.getColumnName())) {
hasColumn = true;
script.append(DMIdentifierProcessor.INSTANCE.quoteIdentifierAlways(column.getColumnName()));
if (!StringUtils.isBlank(column.getAscOrDesc()) && !PRIMARY_KEY.equals(this)) {
script.append(" ").append(DMSqlGuards.requireAscOrDesc(column.getAscOrDesc()));
}
script.append(",");
}
}
if (!hasColumn) {
throw new IllegalArgumentException("DM index must contain at least one named column");
}
script.deleteCharAt(script.length() - 1);
script.append(")");
return script.toString();
}
private String buildIndexName(TableIndex tableIndex) {
return qualifiedName(tableIndex.getSchemaName(), tableIndex.getName());
}
public String buildModifyIndex(TableIndex tableIndex) {
if (EditStatusEnum.DELETE.name().equals(tableIndex.getEditStatus())) {
return buildDropIndex(tableIndex);
}
if (EditStatusEnum.MODIFY.name().equals(tableIndex.getEditStatus())) {
return StringUtils.join(buildDropIndex(tableIndex), ";\n", buildIndexScript(tableIndex));
}
if (EditStatusEnum.ADD.name().equals(tableIndex.getEditStatus())) {View on GitHub (pinned to 5ee1e990e7)
Solutions
- Populate TableIndexColumn.columnName for at least one column before building the index.
- Filter out blank-name columns earlier and skip index generation entirely when none remain.
- Validate the index model in the controller/service layer before reaching the DDL builder.
Example fix
// before
TableIndex idx = new TableIndex();
idx.setColumnList(List.of(new TableIndexColumn())); // name blank
DMIndexTypeEnum.XXX.buildIndexScript(idx);
// after
List<TableIndexColumn> named = idx.getColumnList().stream()
.filter(c -> StringUtils.isNotBlank(c.getColumnName()))
.toList();
if (named.isEmpty()) { /* skip or surface a user error */ }
idx.setColumnList(named);
DMIndexTypeEnum.XXX.buildIndexScript(idx); Defensive patterns
Strategy: validation
Validate before calling
static boolean hasNamedIndexColumn(TableIndex idx) {
if (idx == null || idx.getColumnList() == null) return false;
return idx.getColumnList().stream().anyMatch(c -> StringUtils.isNotBlank(c.getColumnName()));
} Prevention
- Validate that at least one index column has a name before building DM index DDL.
- Filter blank-name columns out of the index model upstream.
- Reject empty-column indexes in the service/controller layer with a clear user message.
When it happens
Trigger: Calling DMIndexTypeEnum.buildIndexScript / buildModifyIndex on a TableIndex whose columnList is non-empty but every TableIndexColumn.getColumnName() is blank, or a list of placeholder rows.
Common situations: A UI 'add index' action that created column rows without binding names; importing an index whose column references were dropped; constructing a TableIndex programmatically and forgetting to populate columnName.
Related errors
- Invalid DM index sort direction: {value}
- Unsupported DM VARCHAR unit: {unit}
- Invalid DM BIT literal: {value}
- Invalid DB2 index column ordering: {ascOrDesc}
- Invalid Hive index sort direction: {value}
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/5950cded63f5053d.
Report an issue: GitHub.