OtterMind/Chat2DB · error · IllegalArgumentException

Invalid SQL Server index column sort order: {ascOrDesc}

Error message

Invalid SQL Server index column sort order: {ascOrDesc}

What it means

Thrown by SqlServerIndexTypeEnum.validateAscOrDesc when an index column's sort order is neither ASC nor DESC (case-insensitive). The value is emitted verbatim into the index DDL, so only the two canonical directions are allowed.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/enums/type/SqlServerIndexTypeEnum.java:113

        StringBuilder script = new StringBuilder();
        script.append("(");
        for (TableIndexColumn column : tableIndex.getColumnList()) {
            if (StringUtils.isNotBlank(column.getColumnName())) {
                script.append(SqlServerIdentifierProcessor.INSTANCE.quoteIdentifierAlways(column.getColumnName()));
                if (!StringUtils.isBlank(column.getAscOrDesc()) && !PRIMARY_KEY.equals(this)) {
                    script.append(" ").append(validateAscOrDesc(column.getAscOrDesc()));
                }
                script.append(",");
            }
        }
        script.deleteCharAt(script.length() - 1);
        script.append(")");
        return script.toString();
    }

    private static String validateAscOrDesc(String ascOrDesc) {
        if (!"ASC".equalsIgnoreCase(ascOrDesc) && !"DESC".equalsIgnoreCase(ascOrDesc)) {
            throw new IllegalArgumentException("Invalid SQL Server index column sort order: " + ascOrDesc);
        }
        return ascOrDesc;
    }

    private String buildIndexName(TableIndex tableIndex) {
        return SqlServerIdentifierProcessor.INSTANCE.quoteIdentifierAlways(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())) {
            return StringUtils.join(buildIndexScript(tableIndex));
        }

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Set ascOrDesc to 'ASC' or 'DESC', or leave it null/blank so the caller skips the validator.
  2. Normalize any third-party metadata to ASC/DESC before populating the index column.
  3. Treat empty sort as 'no direction' rather than sending a placeholder token.

Example fix

// before
col.setAscOrDesc("ASCENDING");
// -> Invalid SQL Server index column sort order

// after
col.setAscOrDesc("ASC");
Defensive patterns

Strategy: validation

Validate before calling

if (StringUtils.isNotBlank(col.getAscOrDesc())
        && !"ASC".equalsIgnoreCase(col.getAscOrDesc())
        && !"DESC".equalsIgnoreCase(col.getAscOrDesc())) {
    throw new IllegalArgumentException("Bad sort order: " + col.getAscOrDesc());
}

Type guard

static boolean isValidAscOrDesc(String v) {
    return v == null || v.isBlank() || "ASC".equalsIgnoreCase(v) || "DESC".equalsIgnoreCase(v);
}

Prevention

When it happens

Trigger: A TableIndexColumn with getAscOrDesc() set to a blank, null, or non-canonical value reaching validateAscOrDesc - e.g. '' , 'A', 'ASCENDING', or 'NULLS FIRST'. (The caller only invokes the validator when the value is non-blank.)

Common situations: Default/empty sort metadata passed as a non-empty placeholder; UI storing a label; cross-dialect data carrying 'NULLS FIRST' which SQL Server indexes do not support per-column.

Related errors


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