{"record":{"id":"295734c51834228e","repo":"apache/cassandra","slug":"unsupported-expression-during-ann-index-query","errorCode":null,"errorMessage":"Unsupported expression during ANN index query: ","messagePattern":"Unsupported expression during ANN index query: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/index/sai/disk/v1/segment/VectorIndexSegmentSearcher.java","lineNumber":120,"sourceCode":"        return graph.ramBytesUsed();\n    }\n\n    @Override\n    public KeyRangeIterator search(Expression expression, AbstractBounds<PartitionPosition> keyRange, QueryContext queryContext) throws IOException\n    {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public CloseableIterator<PrimaryKeyWithScore> orderBy(Expression orderer, AbstractBounds<PartitionPosition> keyRange, QueryContext context) throws IOException\n    {\n        int limit = context.limit();\n\n        if (logger.isTraceEnabled())\n            logger.trace(index.identifier().logMessage(\"Searching on expression '{}'...\"), orderer);\n\n        if (orderer.getIndexOperator() != Expression.IndexOperator.ANN)\n            throw new IllegalArgumentException(index.identifier().logMessage(\"Unsupported expression during ANN index query: \" + orderer));\n\n        int topK = optimizeFor.topKFor(limit);\n\n        float[] queryVector = index.termType().decomposeVector(orderer.lower().value.raw.duplicate());\n        CloseableIterator<RowIdWithScore> result = searchInternal(keyRange, queryVector, limit, topK);\n        return toScoreSortedIterator(result);\n    }\n\n    private CloseableIterator<RowIdWithScore> searchInternal(AbstractBounds<PartitionPosition> keyRange, float[] queryVector, int limit, int topK) throws IOException\n    {\n        try (PrimaryKeyMap primaryKeyMap = primaryKeyMapFactory.newPerSSTablePrimaryKeyMap())\n        {\n            // not restricted\n            if (RangeUtil.coversFullRing(keyRange))\n                return searchInternalUnrestricted(queryVector, limit, topK);\n\n\n            // it will return the next row id if given key is not found.","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sai/disk/v1/segment/VectorIndexSegmentSearcher.java#L102-L138","documentation":"IllegalArgumentException thrown by VectorIndexSegmentSearcher.orderBy when the ORDER BY expression reaching the ANN searcher does not have IndexOperator.ANN. The vector searcher only handles ANN (approximate nearest neighbor) ordering; any other operator means the query was misrouted or used an unsupported operator on a vector index.","triggerScenarios":"Executing an ORDER BY ... ANN query against a vector column where the orderer's index operator is not ANN, e.g. a plain ORDER BY on the vector column, or routing/query-planning bugs that send non-ANN expressions to the vector searcher.","commonSituations":"Malformed CQL ORDER BY clause on a vector index, version skew between planner and searcher code, or attempting similarity search with an operator the vector index does not support.","solutions":["Use the required ANN syntax: ORDER BY vector_col ANN OF [ ... ] LIMIT n","Rewrite the query without the unsupported operator, or filter on a non-vector index instead","Ensure all nodes run the same Cassandra version so planner and searcher agree on routing","If a valid ANN query hits this, file a bug with the exact CQL statement"],"exampleFix":"// before\nSELECT ... FROM t ORDER BY embedding;              // not ANN\n// after\nSELECT ... FROM t ORDER BY embedding ANN OF [0.1, 0.2, ...] LIMIT 10;","handlingStrategy":"validation","validationCode":"if (orderer.getIndexOperator() != Expression.IndexOperator.ANN)\n    throw new IllegalArgumentException(\"ORDER BY on a vector index must use ANN OF\");","typeGuard":"boolean isAnnOrdering(RowIdWithScoreOrderer o) {\n    return o != null && o.getIndexOperator() == Expression.IndexOperator.ANN;\n}","tryCatchPattern":"try {\n    return vectorSearcher.orderBy(orderer, ...);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"Non-ANN ordering rejected: {}\", e.getMessage());\n    throw new InvalidRequestException(\"Use ORDER BY col ANN OF [vector]\");\n}","preventionTips":["Use the documented ANN syntax: ORDER BY vector_col ANN OF [...] LIMIT n","Do not issue plain ORDER BY on vector columns","Keep planner and searcher versions identical across nodes"],"tags":["cassandra","sai","vector-search","ann"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}