{"record":{"id":"48bf0f942c1780d6","repo":"FuelLabs/fuel-core","slug":"fragments-use-different-compressions","errorCode":null,"errorMessage":"Fragments use different compressions.","messagePattern":"Fragments use different compressions\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/chain-config/src/config/state/writer.rs","lineNumber":187,"sourceCode":"                    builder: other_builder,\n                    ..\n                },\n            ) => {\n                builder.merge(other_builder);\n            }\n            #[cfg(feature = \"parquet\")]\n            (\n                FragmentData::Parquet {\n                    tables,\n                    compression,\n                },\n                FragmentData::Parquet {\n                    tables: their_tables,\n                    compression: their_compression,\n                },\n            ) => {\n                tables.extend(their_tables);\n                anyhow::ensure!(\n                    *compression == their_compression,\n                    \"Fragments use different compressions.\"\n                )\n            }\n            #[cfg(feature = \"parquet\")]\n            (a, b) => anyhow::bail!(\n                \"Fragments don't have the same encoding and cannot be merged. Fragments: {a:?} and {b:?}\"\n            ),\n        };\n\n        Ok(self)\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct SnapshotFragment {\n    dir: PathBuf,\n    data: FragmentData,","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/chain-config/src/config/state/writer.rs#L169-L205","documentation":"Snapshot fragments merge only when their parquet compression settings match: merging a Parquet fragment compressed with one ZstdCompressionLevel into another with a different level fails with 'Fragments use different compressions.' (crates/chain-config/src/config/state/writer.rs:187). The compression level is part of the fragment identity because table data is concatenated verbatim. Note the tables vec is extended before the check runs, so a failed merge must be treated as poisoned — the merged value only exists on success.","triggerScenarios":"Calling merge between two fragments produced with different ZstdCompressionLevel values — e.g. parallel snapshot workers each configured with their own level.","commonSituations":"Distributed snapshot generation where worker configs drift; changing compression config between runs and merging fragments from old and new runs.","solutions":["Produce every fragment with the same ZstdCompressionLevel before merging.","Centralize the compression level in one config value shared by all writers/workers.","If levels already differ, re-encode the divergent fragment at the target level instead of merging mixed data."],"exampleFix":"// before\nlet merged = fragment_a.merge(fragment_b)?; // level 3 vs level 22 → error\n\n// after — one shared level for every fragment\nlet level = ZstdCompressionLevel::try_from(3u8)?; // same value everywhere\nlet a = FragmentData::Parquet { tables: a_tables, compression: level };\nlet b = FragmentData::Parquet { tables: b_tables, compression: level };","handlingStrategy":"validation","validationCode":"// Configure every fragment writer from one shared level so merges always agree\nlet level = ZstdCompressionLevel::try_from(3u8)?; // single source of truth\n// pass `level` to every writer/worker that produces fragments","typeGuard":"if let (\n    FragmentData::Parquet { compression: a, .. },\n    FragmentData::Parquet { compression: b, .. },\n) = (&fragment_a.data, &fragment_b.data)\n{\n    anyhow::ensure!(a == b, \"refusing to merge compressions {a:?} and {b:?}\");\n}","tryCatchPattern":"match fragment_a.merge(fragment_b) {\n    Err(e) if e.to_string().contains(\"different compressions\") => {\n        // re-encode one fragment at the other's level, then merge again\n        reencode_fragment(&fragment_b, target_level)?;\n    }\n    other => other?,\n}","preventionTips":["Centralize the compression level in one config shared by all snapshot workers.","Record the level in fragment metadata so merges can pre-check compatibility.","Never mix fragments produced before and after a compression-config change."],"tags":["rust","fuel-core","chain-config","snapshot","compression","merge"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}