{"record":{"id":"a2ae227306075d96","repo":"apache/cassandra","slug":"metadata-cannot-be-null","errorCode":null,"errorMessage":"metadata cannot be null","messagePattern":"metadata cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/util/MmappedRegions.java","lineNumber":107,"sourceCode":"    {\n        super(original);\n        this.state = original.copy;\n    }\n\n    public static MmappedRegions empty(ChannelProxy channel)\n    {\n        return new MmappedRegions(new State(channel), 0, 0);\n    }\n\n    /**\n     * @param channel  file to map. the MmappedRegions instance will hold shared copy of given channel.\n     * @param metadata\n     * @return new instance\n     */\n    public static MmappedRegions map(ChannelProxy channel, CompressionMetadata metadata)\n    {\n        if (metadata == null)\n            throw new IllegalArgumentException(\"metadata cannot be null\");\n        State state = new State(channel);\n        return new MmappedRegions(state, metadata);\n    }\n\n    public static MmappedRegions map(ChannelProxy channel, long length, int chunkSize)\n    {\n        if (length <= 0)\n            throw new IllegalArgumentException(\"Length must be positive\");\n        State state = new State(channel);\n        return new MmappedRegions(state, length, chunkSize);\n    }\n\n    /**\n     * @return a snapshot of the memory mapped regions. The snapshot can\n     * only use existing regions, it cannot create new ones.\n     */\n    public MmappedRegions sharedCopy()\n    {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/MmappedRegions.java#L89-L125","documentation":"MmappedRegions.map(ChannelProxy, CompressionMetadata) requires a non-null compression metadata because the mmap window layout is driven by the compressed chunk index. A null CompressionMetadata means the caller has confused the compressed-file overload with the plain length-based map(channel, length, chunkSize) overload.","triggerScenarios":"Calling MmappedRegions.map(channel, (CompressionMetadata) null) — typically by passing a variable that is null because the file was not compressed, or by passing the wrong field (null metadata for uncompressed sstables) into the compressed-file overload.","commonSituations":"Code handling both compressed and uncompressed SSTables that forget to branch: CompressionMetadata for a compressed file is obtained from CompressionMetadata.create(path); for uncompressed files it is null and the length-based map() overload must be used instead.","solutions":["Pass a valid CompressionMetadata created via CompressionMetadata.create(filePath) for compressed files","Use the length-based overload MmappedRegions.map(channel, length, chunkSize) when the file has no compression metadata","Add a null check / branch on metadata before calling map so uncompressed files take the plain path"],"exampleFix":"// before\nCompressionMetadata metadata = descriptorMayOrMayNotBeCompressed ? null : null;\nMmappedRegions regions = MmappedRegions.map(channel, metadata); // IAE: metadata cannot be null\n// after\nCompressionMetadata metadata = CompressionMetadata.create(channel.path());\nif (metadata != null) {\n    regions = MmappedRegions.map(channel, metadata);\n} else {\n    regions = MmappedRegions.map(channel, fileLength, chunkSize);\n}","handlingStrategy":"validation","validationCode":"if (metadata == null) { regions = MmappedRegions.map(channel, length, chunkSize); } else { regions = MmappedRegions.map(channel, metadata); }","typeGuard":"boolean compressed = metadata != null;","tryCatchPattern":"try { regions = MmappedRegions.map(channel, metadata); } catch (IllegalArgumentException e) { regions = MmappedRegions.map(channel, channel.size(), DEFAULT_CHUNK_SIZE); }","preventionTips":["Branch on file compression before choosing the map overload","Only obtain CompressionMetadata for files known to be compressed","Add null-guards at the call site for shared code paths"],"tags":["io","mmap","null-argument"],"backgroundTag":"null-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"}