OtterMind/Chat2DB · error · IllegalArgumentException

Invalid DM index sort direction: {value}

Error message

Invalid DM index sort direction: {value}

What it means

Thrown by DMSqlGuards.requireAscOrDesc when an index sort direction is neither ASC nor DESC. Unlike the DB2 variant, this method normalizes the value to canonical uppercase before returning, but it still rejects every other token. It is used inside DM index DDL generation to keep non-escapable ordering tokens safe.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-dm/src/main/java/ai/chat2db/plugin/dm/DMSqlGuards.java:65

    }

    public static String requireUnit(String unit) {
        String trimmed = StringUtils.trimToEmpty(unit);
        if (!"CHAR".equalsIgnoreCase(trimmed) && !"BYTE".equalsIgnoreCase(trimmed)) {
            throw new IllegalArgumentException("Unsupported DM VARCHAR unit: " + unit);
        }
        return trimmed;
    }

    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 DM index sort direction: " + value);
    }

    public static String requireBitLiteral(String value) {
        if (StringUtils.isBlank(value)) {
            return "NULL";
        }
        String trimmed = StringUtils.trimToEmpty(value);
        if ("0".equals(trimmed) || "false".equalsIgnoreCase(trimmed)) {
            return "0";
        }
        if ("1".equals(trimmed) || "true".equalsIgnoreCase(trimmed)) {
            return "1";
        }
        throw new IllegalArgumentException("Invalid DM BIT literal: " + value);
    }

    private static void scanExpression(String expression, boolean typeExpression, String description) {
        Deque<Character> delimiters = new ArrayDeque<>();

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Ensure ascOrDesc is "ASC", "DESC", or blank (blank is skipped by the caller before requireAscOrDesc runs).
  2. Map foreign sort-direction codes to ASC/DESC at the metadata import boundary.
  3. For primary-key-style indexes the check is bypassed; verify the index type is correctly set to PRIMARY_KEY when you intend to skip direction validation.

Example fix

// before
column.setAscOrDesc("N"); // non-standard
DMSqlGuards.requireAscOrDesc(column.getAscOrDesc());

// after
String dir = column.getAscOrDesc();
dir = "N".equalsIgnoreCase(dir) ? null : dir;
column.setAscOrDesc(dir); // blank -> skipped; otherwise ASC/DESC
Defensive patterns

Strategy: validation

Validate before calling

static boolean isDmDir(String v) {
    return v != null && ("ASC".equalsIgnoreCase(v.trim()) || "DESC".equalsIgnoreCase(v.trim()));
}

Type guard

static String dmDirOrNull(String v) {
    if (v == null) return null;
    String t = v.trim();
    if ("ASC".equalsIgnoreCase(t)) return "ASC";
    if ("DESC".equalsIgnoreCase(t)) return "DESC";
    return null;
}

Prevention

When it happens

Trigger: Calling DMSqlGuards.requireAscOrDesc(value) with a value that trims to something other than ASC/DESC, or invoking DMIndexTypeEnum.buildIndexScript on an index whose column.ascOrDesc carries a bad token (and the index type is not PRIMARY_KEY, which skips the check).

Common situations: Index metadata imported from a non-DM source with a free-text sort field; a column model reused across dialects where another DB stored an unsupported direction; UI defaulting ascOrDesc to a placeholder like "NONE".

Related errors


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