OtterMind/Chat2DB · error · IllegalArgumentException

Invalid Snowflake index sort direction: {value}

Error message

Invalid Snowflake index sort direction: {value}

What it means

Thrown by SnowflakeSqlGuards.requireAscOrDesc when the value is not ASC or DESC (case-insensitive). This validates index sort direction in Snowflake DDL generation, where only ascending and descending are legal. The method trims input and uses equalsIgnoreCase, so 'asc', 'Asc', 'ASC' all pass, but 'ASCENDING', 'ascending', 'A', or any other value fails.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeSqlGuards.java:101

        if (expression.isEmpty()) {
            throw invalid("cluster by clause", value);
        }
        scanExpression(expression, CLAUSE_BREAKOUT_KEYWORDS, false, "cluster by clause");
        return "CLUSTER BY " + expression;
    }

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

    private static void scanExpression(String expression, Set<String> breakoutKeywords,
                                       boolean allowTopLevelComma, String description) {
        Deque<Character> delimiters = new ArrayDeque<>();
        boolean sawContent = false;
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '\'' || c == '"') {
                i = scanQuoted(expression, i, c, description);
                sawContent = true;
                continue;
            }
            if (startsWith(expression, i, "--") || startsWith(expression, i, "/*")
                    || startsWith(expression, i, "*/") || c == ';' || c == '\n' || c == '\r'
                    || Character.isISOControl(c)) {
                throw invalid(description, expression);
            }

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Normalize the input to 'ASC' or 'DESC' before calling requireAscOrDesc
  2. Use a constrained UI control (radio button or dropdown) that only offers ASC/DESC choices
  3. Default unset values to 'ASC' before validation

Example fix

// before
SnowflakeSqlGuards.requireAscOrDesc("ASCENDING");

// after
String direction = "ASCENDING".startsWith("ASC") ? "ASC" : "DESC";
SnowflakeSqlGuards.requireAscOrDesc(direction);
Defensive patterns

Strategy: validation

Validate before calling

public static String normalizeSortDirection(String value) {
    if (value == null || value.isBlank()) return "ASC";
    String upper = value.trim().toUpperCase(Locale.ROOT);
    if (upper.startsWith("ASC")) return "ASC";
    if (upper.startsWith("DESC")) return "DESC";
    throw new IllegalArgumentException("Sort direction must be ASC or DESC, got: " + value);
}

Type guard

public static boolean isValidSortDirection(String value) {
    if (value == null) return false;
    String trimmed = value.trim();
    return "ASC".equalsIgnoreCase(trimmed) || "DESC".equalsIgnoreCase(trimmed);
}

Prevention

When it happens

Trigger: Calling SnowflakeSqlGuards.requireAscOrDesc(value) where value is null, blank, or not equal to ASC or DESC ignoring case. Common invalid values: 'ASCENDING', 'DESCENDING', 'ascending', '', null, 'A', 'D', 'asc/desc'.

Common situations: A UI dropdown or form field that allows free-text sort direction entry; metadata from a source that uses full words instead of abbreviations; a configuration typo; a default value that was never set (null or empty string).

Related errors


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