{"record":{"id":"102f239fc94bb410","repo":"apache/cassandra","slug":"value-for-a-map-substraction-has-to-be-a-set-but","errorCode":null,"errorMessage":"Value for a map substraction has to be a set, but was: '%s'","messagePattern":"Value for a map substraction has to be a set, but was: '(.+?)'","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/Operation.java","lineNumber":434,"sourceCode":"            {\n                case LIST:\n                    return new Lists.Discarder(receiver, value.prepare(metadata.keyspace, receiver));\n                case SET:\n                    return new Sets.Discarder(receiver, value.prepare(metadata.keyspace, receiver));\n                case MAP:\n                    // The value for a map subtraction is actually a set\n                    ColumnSpecification vr = new ColumnSpecification(receiver.ksName,\n                                                                     receiver.cfName,\n                                                                     receiver.name,\n                                                                     SetType.getInstance(((MapType<?, ?>) receiver.type).getKeysType(), true));\n                    Term term;\n                    try\n                    {\n                        term = value.prepare(metadata.keyspace, vr);\n                    }\n                    catch (InvalidRequestException e)\n                    {\n                        throw new InvalidRequestException(String.format(\"Value for a map substraction has to be a set, but was: '%s'\", value));\n                    }\n                    return new Sets.Discarder(receiver, term);\n            }\n            throw new AssertionError();\n        }\n\n        protected String toString(ColumnSpecification column)\n        {\n            return String.format(\"%s = %s - %s\", column.name, column.name, value);\n        }\n\n        public boolean isCompatibleWith(RawUpdate other)\n        {\n            return !(other instanceof SetValue);\n        }\n    }\n\n    public static class Prepend implements RawUpdate","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/Operation.java#L416-L452","documentation":"For a map subtraction (`m = m - ...`), the value term must prepare as a set of keys; the provided term failed its prepare() against that spec, so it is wrapped into this clearer error. The thrown message discards the underlying InvalidRequestException cause.","triggerScenarios":"`UPDATE t SET m = m - ?` where the bound value is not a set of the map's key type (e.g. a full map, a list, or a wrong key type); malformed set literal.","commonSituations":"Binding a Map instead of Set<K> of keys to remove; driver type mismatch; copying map-addition code (which takes a map) to subtraction without changing the argument type.","solutions":["Pass a Set<K> of the keys to remove (not a Map) when subtracting from a map column","Validate the key type matches the map's key type exactly","Fix literal syntax: m = m - {key1, key2}","Inspect the original cause by preparing the value separately if needed"],"exampleFix":"// before\nMap<String,Integer> m = Map.of(\"k\",1);\nsession.execute(\"UPDATE t SET m = m - ?\", m);\n// after\nSet<String> keys = Set.of(\"k\");\nsession.execute(\"UPDATE t SET m = m - ?\", keys);","handlingStrategy":"validation","validationCode":"if (!(keysToRemove instanceof Set<?> s)) throw new IllegalArgumentException(\"map subtraction requires a Set of keys\");","typeGuard":"static boolean isSet(Object v){ return v instanceof Set; }","tryCatchPattern":"try { session.execute(ps.bind(keySet)); } catch (InvalidQueryException e) { if (e.getMessage().contains(\"has to be a set\")) { /* pass Set<K> instead */ } else throw e; }","preventionTips":["Always pass Set<K> of keys for map subtraction, never a Map","Keep key types exactly matching the map key type","Double-check argument order/semantics when reusing add code for subtract"],"tags":["cql","collections","type-mismatch","maps"],"backgroundTag":"invalid-argument-value","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"}