{"record":{"id":"5be1d9059b0a43c9","repo":"apache/cassandra","slug":"invalid-unset-map-key","errorCode":null,"errorMessage":"Invalid unset map key","messagePattern":"Invalid unset map key","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/terms/Maps.java","lineNumber":293,"sourceCode":"            this.k = k;\n        }\n\n        @Override\n        public void collectMarkerSpecification(VariableSpecifications boundNames, Object owner)\n        {\n            super.collectMarkerSpecification(boundNames, owner);\n            k.collectMarkerSpecification(boundNames, owner);\n        }\n\n        public void execute(DecoratedKey partitionKey, RowUpdateBuilder builder) throws InvalidRequestException\n        {\n            assert column.type.isMultiCell() : \"Attempted to set a value for a single key on a frozen map\";\n            ByteBuffer key = k.bindAndGet(builder);\n            ByteBuffer value = t.bindAndGet(builder);\n            if (key == null)\n                throw new InvalidRequestException(\"Invalid null map key\");\n            if (key == ByteBufferUtil.UNSET_BYTE_BUFFER)\n                throw new InvalidRequestException(\"Invalid unset map key\");\n\n            CellPath path = CellPath.create(key);\n\n            if (value == null)\n            {\n                builder.addTombstone(column, path);\n            }\n            else if (value != ByteBufferUtil.UNSET_BYTE_BUFFER)\n            {\n                builder.addCell(column, path, value);\n            }\n        }\n    }\n\n    public static class Putter extends Operation\n    {\n        public Putter(ColumnMetadata column, Term t)\n        {","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/terms/Maps.java#L275-L311","documentation":"Thrown at execution when the key bound for a single-key map write is the UNSET sentinel rather than a real value. UNSET means 'do not modify' and is not valid for identifying a map entry, so the request fails.","triggerScenarios":"Executing `UPDATE t SET m[?] = ? WHERE ...` where the driver bound the key as unset (UNSET_VALUE / unset bind parameter).","commonSituations":"Batch builders that mark parameters unset for conditional writes; drivers' unset-value support applied to map keys; templated code that omits keys but keeps the statement.","solutions":["Bind a concrete key value; use null (which also errors) only deliberately — for 'skip' semantics restructure the statement.","Build the statement conditionally so unset keys produce no map-key clause.","Use a whole-map assignment `SET m = ?` when the full map is known."],"exampleFix":"// before\nboundStatement.setBytesToUnset(i); // key\n// after\nboundStatement.setString(i, actualKey); // must be a real key value","handlingStrategy":"validation","validationCode":"if (isUnset(mapKey)) throw new IllegalArgumentException(\"map key must be a concrete value, not UNSET\");","typeGuard":"boolean isConcrete(ByteBuffer b) { return b != null && b != ByteBufferUtil.UNSET_BYTE_BUFFER; }","tryCatchPattern":"try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().contains(\"Invalid unset map key\")) { /* provide a real key or restructure */ } else throw e; }","preventionTips":["Do not use unset semantics for collection keys","Build statements conditionally instead of binding unset values","Reserve UNSET for whole-column omission, not per-key access"],"tags":["cql","map","unset-value","invalid-request"],"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-17T15:17:12.973Z"}