{"record":{"id":"ba94a6fc107aa7ad","repo":"apache/cassandra","slug":"invalid-unset-value-for-list-index","errorCode":null,"errorMessage":"Invalid unset value for list index","messagePattern":"Invalid unset value for list index","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/terms/Lists.java","lineNumber":366,"sourceCode":"            super.collectMarkerSpecification(boundNames, owner);\n            idx.collectMarkerSpecification(boundNames, owner);\n        }\n\n        public void execute(DecoratedKey partitionKey, RowUpdateBuilder builder) throws InvalidRequestException\n        {\n            // we should not get here for frozen lists\n            assert column.type.isMultiCell() : \"Attempted to set an individual element on a frozen list\";\n\n            Guardrails.readBeforeWriteListOperationsEnabled\n            .ensureEnabled(\"Setting of list items by index requiring read before write\", builder.clientState);\n\n            ByteBuffer index = idx.bindAndGet(builder);\n            ByteBuffer value = t.bindAndGet(builder);\n\n            if (index == null)\n                throw new InvalidRequestException(\"Invalid null value for list index\");\n            if (index == ByteBufferUtil.UNSET_BYTE_BUFFER)\n                throw new InvalidRequestException(\"Invalid unset value for list index\");\n\n            Row existingRow = builder.getPrefetchedRow(partitionKey, builder.currentClustering());\n            int existingSize = existingSize(existingRow, column);\n            int idx = ByteBufferUtil.toInt(index);\n            if (existingSize == 0)\n                throw new InvalidRequestException(\"Attempted to set an element on a list which is null\");\n            if (idx < 0 || idx >= existingSize)\n                throw new InvalidRequestException(String.format(\"List index %d out of bound, list has size %d\", idx, existingSize));\n\n            CellPath elementPath = existingRow.getComplexColumnData(column).getCellByIndex(idx).path();\n            if (value == null)\n                builder.addTombstone(column, elementPath);\n            else if (value != ByteBufferUtil.UNSET_BYTE_BUFFER)\n                builder.addCell(column, elementPath, value);\n        }\n    }\n\n    public static class Appender extends Operation","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/terms/Lists.java#L348-L384","documentation":"Thrown when the index of a list element assignment is left UNSET (the driver's explicit 'unset' marker, distinct from null). Indexed list writes require a concrete index; unset would make the operation nondeterministic, so it is rejected.","triggerScenarios":"`UPDATE t SET l[?] = ?` where the index parameter is bound to the driver's unset value (e.g. unsetValue() in the Java driver).","commonSituations":"Reusing a generic 'update all fields or leave unset' binding helper for indexed list operations; templated batch code that marks all optional params unset.","solutions":["Always bind an actual integer index for l[?] operations — unset is not allowed","Construct a different statement (whole-list assignment or removal) when the index is not known","Restrict generic unset-based bind helpers to non-indexed operations"],"exampleFix":"// before\nps.setBytesUnsafe(0, unset); // unset index\n// after\nif (index == null) throw new IllegalArgumentException(\"list index required\");\nps.setInt(0, index);","handlingStrategy":"validation","validationCode":"if (index == null || isUnset(index)) throw new IllegalArgumentException(\"list index must be bound, not unset\");","typeGuard":null,"tryCatchPattern":"try { session.execute(stmt); } catch (InvalidQueryException e) { if (e.getMessage().contains(\"Invalid unset value for list index\")) { /* bind a real index */ } else throw e; }","preventionTips":["Never use driver unset values for indexed list writes","Don't route indexed ops through generic unset-all-optional binders","Construct explicit statements for l[i] updates"],"tags":["cql","list","unset-value","bind-parameter"],"backgroundTag":"missing-required-argument","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"}