{"record":{"id":"f61021070e42f02f","repo":"apache/cassandra","slug":"invalid-null-value-in-map","errorCode":null,"errorMessage":"Invalid null value in map","messagePattern":"Invalid null value in map","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/MapType.java","lineNumber":350,"sourceCode":"    @Override\n    public Term fromJSONObject(Object parsed) throws MarshalException\n    {\n        if (parsed instanceof String)\n            parsed = JsonUtils.decodeJson((String) parsed);\n\n        if (!(parsed instanceof Map))\n            throw new MarshalException(String.format(\n                    \"Expected a map, but got a %s: %s\", parsed.getClass().getSimpleName(), parsed));\n\n        Map<?, ?> map = (Map<?, ?>) parsed;\n        List<Term> terms = new ArrayList<>(map.size() << 1);\n        for (Map.Entry<?, ?> entry : map.entrySet())\n        {\n            if (entry.getKey() == null)\n                throw new MarshalException(\"Invalid null key in map\");\n\n            if (entry.getValue() == null)\n                throw new MarshalException(\"Invalid null value in map\");\n\n            terms.add(keys.fromJSONObject(entry.getKey()));\n            terms.add(values.fromJSONObject(entry.getValue()));\n        }\n        return new MultiElements.DelayedValue(this, terms);\n    }\n\n    @Override\n    public String toJSONString(ByteBuffer buffer, ProtocolVersion protocolVersion)\n    {\n        ByteBuffer value = buffer.duplicate();\n        StringBuilder sb = new StringBuilder(\"{\");\n        int size = CollectionSerializer.readCollectionSize(value, ByteBufferAccessor.instance);\n        int offset = CollectionSerializer.sizeOfCollectionSize();\n        for (int i = 0; i < size; i++)\n        {\n            if (i > 0)\n                sb.append(\", \");","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/MapType.java#L332-L368","documentation":"MapType.fromJSONObject() rejects any map entry whose value is null, since Cassandra collection values cannot be null. Each decoded entry's value is checked before element terms are built; a null value raises MarshalException.","triggerScenarios":"Calling fromJSONObject on MapType with a decoded Map containing a null value — e.g. JSON like {\"m\": {\"a\": null}}.","commonSituations":"Client code emitting JSON null for absent values instead of omitting the key; ingestion pipelines preserving nulls from upstream data; partial updates expressed as nulls in map fields.","solutions":["Remove keys with null values from the JSON object, or set explicit non-null values.","Use a DELETE/UNSET statement for removal semantics instead of sending null values.","Filter null values from the decoded Map before calling fromJSONObject."],"exampleFix":"// before\n{\"m\": {\"a\": 1, \"b\": null}}\n// after\n{\"m\": {\"a\": 1}}","handlingStrategy":"validation","validationCode":"Map<?,?> map = (Map<?,?>) decoded;\nif (map.values().stream().anyMatch(Objects::isNull))\n    throw new IllegalArgumentException(\"map contains a null value\");","typeGuard":null,"tryCatchPattern":"try {\n    Term term = mapType.fromJSONObject(parsed);\n} catch (MarshalException e) {\n    if (e.getMessage().contains(\"null value\")) {\n        // strip null-value entries or reject record\n    }\n}","preventionTips":["Omit keys entirely instead of setting them to null in JSON","Use DELETE statements for removal semantics","Sanitize decoded maps: entries.removeIf(e -> e.getValue() == null)"],"tags":["cassandra","json","map","null"],"backgroundTag":"null-argument","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"}