{"record":{"id":"67e773690c03ce30","repo":"apache/cassandra","slug":"counters-are-not-allowed-inside-collections","errorCode":null,"errorMessage":"Counters are not allowed inside collections: ","messagePattern":"Counters are not allowed inside collections: ","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/CQL3Type.java","lineNumber":865,"sourceCode":"                return prepare(keyspace, udts, false);\n            }\n\n            public CQL3Type prepareInternal(String keyspace, Types udts)\n            {\n                return prepare(keyspace, udts, true);\n            }\n\n            public CQL3Type prepare(String keyspace, Types udts, boolean isInternal) throws InvalidRequestException\n            {\n                assert values != null : \"Got null values type for a collection\";\n\n                if (!frozen && values.supportsFreezing() && !values.frozen)\n                    throwNestedNonFrozenError(values);\n\n                // we represent supercolumns as maps, internally, and we do allow counters in supercolumns. Thus,\n                // for internal type parsing (think schema) we have to make an exception and allow counters as (map) values\n                if (values.isCounter() && !isInternal)\n                    throw new InvalidRequestException(\"Counters are not allowed inside collections: \" + this);\n\n                if (values.isDuration() && kind == Kind.SET)\n                    throw new InvalidRequestException(\"Durations are not allowed inside sets: \" + this);\n\n                if (keys != null)\n                {\n                    if (keys.isCounter())\n                        throw new InvalidRequestException(\"Counters are not allowed inside collections: \" + this);\n                    if (keys.isDuration())\n                        throw new InvalidRequestException(\"Durations are not allowed as map keys: \" + this);\n                    if (!frozen && keys.supportsFreezing() && !keys.frozen)\n                        throwNestedNonFrozenError(keys);\n                }\n\n                AbstractType<?> valueType = values.prepare(keyspace, udts).getType();\n                switch (kind)\n                {\n                    case LIST:","sourceCodeStart":847,"sourceCodeEnd":883,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/CQL3Type.java#L847-L883","documentation":"Cassandra rejects counter columns used as elements or values of any collection type (list, set, map value) unless the parse is internal (supercolumn schema compatibility). Counters cannot be embedded in collections because counter updates are deltas merged per-cell, which the collection conflict resolution cannot support.","triggerScenarios":"Declaring a column like `set<counter>`, `list<counter>`, or `map<text, counter>` in CREATE TABLE / ALTER TABLE, or using counter inside a nested collection type definition.","commonSituations":"Developers trying to keep per-item counters in a set or map instead of using one counter column per row; schema migrations porting from other databases.","solutions":["Move the counter to a top-level column: `counter_val counter` keyed by the item id in the primary key instead of a map of counters","Use a frozen<...> wrapper only if the whole collection is truly static and updated wholesale — but note frozen collections still cannot contain counters; prefer per-row counters","Model counters in a separate table with one counter column per entity","If this is internal schema parsing of legacy supercolumn data, it is not a user error — do not attempt to fix in user CQL"],"exampleFix":"// before\nCREATE TABLE stats (id uuid PRIMARY KEY, per_item map<text, counter>);\n// after\nCREATE TABLE stats (id uuid, item text, hits counter, PRIMARY KEY (id, item));","handlingStrategy":"validation","validationCode":"boolean usesCounterInCollection(String cqlTypeDecl) {\n    String lower = cqlTypeDecl.toLowerCase();\n    return lower.matches(\"(list|set|map)\\\\s*<.*counter.*\");\n}\n// call before issuing CREATE TABLE/ALTER TABLE","typeGuard":null,"tryCatchPattern":"try { session.execute(schemaDdl); } catch (com.datastax.driver.core.exceptions.InvalidQueryException e) { if (e.getMessage().contains(\"Counters are not allowed inside collections\")) { /* redesign schema: counters as top-level columns */ } else throw e; }","preventionTips":["Never declare counter inside list/set/map/tuple — counters must be top-level columns","Model per-entity counters with a separate table and clustering key","Validate schema DDL in a test keyspace before applying to production"],"tags":["cql","schema","counter","collection"],"backgroundTag":"schema-validation-failed","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"}