{"record":{"id":"9194880ff14fbc3e","repo":"apache/cassandra","slug":"cql-type-s-cannot-have-vector-options","errorCode":null,"errorMessage":"CQL type %s cannot have vector options","messagePattern":"CQL type (.+?) cannot have vector options","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/index/sai/disk/v1/IndexWriterConfig.java","lineNumber":118,"sourceCode":"    public OptimizeFor getOptimizeFor()\n    {\n        return optimizeFor;\n    }\n\n    public static IndexWriterConfig fromOptions(String indexName, IndexTermType indexTermType, Map<String, String> options)\n    {\n        int maximumNodeConnections = DEFAULT_MAXIMUM_NODE_CONNECTIONS;\n        int queueSize = DEFAULT_CONSTRUCTION_BEAM_WIDTH;\n        VectorSimilarityFunction similarityFunction = DEFAULT_SIMILARITY_FUNCTION;\n        OptimizeFor optimizeFor = DEFAULT_OPTIMIZE_FOR;\n\n        if (options.get(MAXIMUM_NODE_CONNECTIONS) != null ||\n            options.get(CONSTRUCTION_BEAM_WIDTH) != null ||\n            options.get(SIMILARITY_FUNCTION) != null ||\n            options.get(OPTIMIZE_FOR) != null)\n        {\n            if (!indexTermType.isVector())\n                throw new InvalidRequestException(String.format(\"CQL type %s cannot have vector options\", indexTermType.asCQL3Type()));\n\n            if (options.containsKey(MAXIMUM_NODE_CONNECTIONS))\n            {\n                if (!CassandraRelevantProperties.SAI_VECTOR_ALLOW_CUSTOM_PARAMETERS.getBoolean())\n                    throw new InvalidRequestException(String.format(\"Maximum node connections cannot be set without enabling %s\", CassandraRelevantProperties.SAI_VECTOR_ALLOW_CUSTOM_PARAMETERS.name()));\n\n                try\n                {\n                    maximumNodeConnections = Integer.parseInt(options.get(MAXIMUM_NODE_CONNECTIONS));\n                }\n                catch (NumberFormatException e)\n                {\n                    throw new InvalidRequestException(String.format(\"Maximum number of connections %s is not a valid integer for index %s\",\n                                                                    options.get(MAXIMUM_NODE_CONNECTIONS), indexName));\n                }\n                if (maximumNodeConnections <= 0 || maximumNodeConnections > MAXIMUM_MAXIMUM_NODE_CONNECTIONS)\n                    throw new InvalidRequestException(String.format(\"Maximum number of connections for index %s cannot be <= 0 or > %s, was %s\", indexName, MAXIMUM_MAXIMUM_NODE_CONNECTIONS, maximumNodeConnections));\n            }","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sai/disk/v1/IndexWriterConfig.java#L100-L136","documentation":"Thrown by IndexWriterConfig.fromOptions when a SAI index on a non-vector column specifies vector-only options (maximum_node_connections, construction_beam_width, similarity_function, optimize_for). These options only make sense for vector (ANN) indexes, so Cassandra rejects the request.","triggerScenarios":"CREATE CUSTOM INDEX on a scalar/text column USING 'StorageAttachedIndex' WITH OPTIONS containing any of similarity_function, maximum_node_connections, construction_beam_width, or optimize_for; indexTermType.isVector() is false.","commonSituations":"Copy-pasting a vector index definition and changing only the column; applying a shared WITH OPTIONS map to mixed-type columns; tooling that emits a uniform option set.","solutions":["Remove the vector-only options from the non-vector index definition","Recreate the index on the actual vector column if ANN search was intended","Split the options map so scalar columns get their own options","Check the column type (vector<float, N>) before adding vector options"],"exampleFix":"// before\nCREATE CUSTOM INDEX ON ks.tbl (name) USING 'StorageAttachedIndex'\n  WITH OPTIONS = {'similarity_function': 'COSINE'};\n// after\nCREATE CUSTOM INDEX ON ks.tbl (name) USING 'StorageAttachedIndex';","handlingStrategy":"validation","validationCode":"Set<String> vectorOnly = Set.of(\"maximum_node_connections\",\"construction_beam_width\",\"similarity_function\",\"optimize_for\");\nif (!columnType.startsWith(\"vector<\") && opts.keySet().stream().anyMatch(vectorOnly::contains))\n    throw new IllegalArgumentException(\"Vector-only options applied to non-vector column\");","typeGuard":null,"tryCatchPattern":"try { session.execute(createIndexCql); }\ncatch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"cannot have vector options\")) { /* strip vector options or retarget index */ }\n    else throw e;\n}","preventionTips":["Maintain separate option sets for vector and non-vector SAI indexes","Check the column's CQL type before attaching index options","Avoid sharing one WITH OPTIONS map across heterogeneous columns"],"tags":["cassandra","cql","sai","vector-index","options"],"backgroundTag":"unsupported-config-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}