apache/cassandra · error · InvalidRequestException

selection is only allowed on sets and maps, but is a list

Error message

%s selection is only allowed on sets and maps, but %s is a list

What it means

Element or slice selection (x[i], x[a..b]) is only defined for sets and maps. CollectionType.Kind LIST is rejected because positional list indexing in the selection clause is not supported, and specForElementOrSlice has no valid receiver spec for a list.

Solutions

  1. Fetch the whole list and index it client-side
  2. Convert the column to a map (e.g. map<int,text>) keyed by index if positional selection is genuinely needed
  3. Use UPDATE ... SET l[i] = x for writes; selection of list elements is unsupported

Example fix

// before
SELECT tags[0] FROM t;
// after
SELECT tags FROM t; // index client-side
Defensive patterns

Strategy: validation

Validate before calling

if (columnMetadata.getType() instanceof ListType)
    throw new IllegalArgumentException("element/slice selection not allowed on list column " + col);

Prevention

When it happens

Trigger: SELECT mylist[0] FROM t — attempting element selection on a column whose type is a frozen/multi-cell list.

Common situations: Developers familiar with array indexing try positional access on list columns in SELECT; lists only support indexed update in CQL, not element selection in the projection.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/2a896256d46becb0. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/selection/Selectable.java:150

        return getExactTypeIfKnown(keyspace);
    }

    default int addAndGetIndex(ColumnMetadata def, List<ColumnMetadata> l)
    {
        int idx = l.indexOf(def);
        if (idx < 0)
        {
            idx = l.size();
            l.add(def);
        }
        return idx;
    }

    default ColumnSpecification specForElementOrSlice(Selectable selected, ColumnSpecification receiver, CollectionType.Kind kind, String selectionType)
    {
        switch (kind)
        {
            case LIST: throw new InvalidRequestException(String.format("%s selection is only allowed on sets and maps, but %s is a list", selectionType, selected));
            case SET: return Sets.valueSpecOf(receiver);
            case MAP: return Maps.keySpecOf(receiver);
            default: throw new AssertionError();
        }
    }

    public interface Raw
    {
        public Selectable prepare(TableMetadata table);
    }

    public static class WithTerm implements Selectable
    {
        /**
         * The names given to unamed bind markers found in selection. In selection clause, we often don't have a good
         * name for bind markers, typically if you have:
         *   SELECT (int)? FROM foo;
         * there isn't a good name for that marker. So we give the same name to all the markers. Note that we could try

View on GitHub (pinned to 88fd0f6a0e)