{"record":{"id":"5af6d3fa61c87d3c","repo":"FuelLabs/fuel-core","slug":"no-block-height-found","errorCode":null,"errorMessage":"No block height found","messagePattern":"No block height found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/chain-config/src/config/state/reader.rs","lineNumber":208,"sourceCode":"            data_source: DataSource::Parquet {\n                tables,\n                latest_block_config,\n            },\n            chain_config,\n        })\n    }\n\n    #[cfg(feature = \"parquet\")]\n    fn read_config<Config>(path: &std::path::Path) -> anyhow::Result<Config>\n    where\n        Config: serde::de::DeserializeOwned,\n    {\n        use super::parquet::decode::Decoder;\n\n        let file = std::fs::File::open(path)?;\n        let group = Decoder::new(file)?\n            .next()\n            .ok_or_else(|| anyhow::anyhow!(\"No block height found\"))??;\n        let config = group\n            .into_iter()\n            .next()\n            .ok_or_else(|| anyhow::anyhow!(\"No config found\"))?;\n        postcard::from_bytes(&config).map_err(Into::into)\n    }\n\n    #[cfg(feature = \"std\")]\n    pub fn open(\n        snapshot_metadata: crate::config::SnapshotMetadata,\n    ) -> anyhow::Result<Self> {\n        Self::open_w_config(snapshot_metadata, MAX_GROUP_SIZE)\n    }\n\n    #[cfg(feature = \"std\")]\n    pub fn open_w_config(\n        snapshot_metadata: crate::config::SnapshotMetadata,\n        json_group_size: usize,","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/chain-config/src/config/state/reader.rs#L190-L226","documentation":"When reading a parquet-encoded snapshot table, Reader::read_config takes the first row group from the decoder, whose first row carries the block height and config payload. If the decoder yields no row group at all, reading fails with 'No block height found' (crates/chain-config/src/config/state/reader.rs:208). In practice the file exists but is empty or header-only — a table that was created but never written, or truncated.","triggerScenarios":"StateReader::open / open_w_config (or read_config directly) on a snapshot directory where a table's parquet file is 0 bytes or contains zero row groups.","commonSituations":"Interrupted snapshot generation (process killed mid-write, writer's close() never ran); copying a snapshot and missing file contents; pointing SnapshotMetadata at the wrong directory whose expected tables were never produced; filesystem truncation.","solutions":["Regenerate the snapshot end-to-end, letting the writer finish and close all row groups.","Before opening, verify each table file is non-empty and plausibly sized.","Check that SnapshotMetadata (directory + table list) matches the files actually on disk.","If generating snapshots programmatically, ensure the writer's close() runs even on early exits."],"exampleFix":"// before — fails with 'No block height found' on an empty table\nlet reader = StateReader::open(snapshot_metadata)?;\n\n// after — guard against empty/truncated tables first\nfor table in &expected_tables {\n    let path = snapshot_dir.join(table);\n    let len = std::fs::metadata(&path)\n        .with_context(|| format!(\"missing snapshot table {path:?}\"))?\n        .len();\n    anyhow::ensure!(len > 0, \"snapshot table {table} is empty ({len} bytes)\");\n}","handlingStrategy":"validation","validationCode":"// Reject empty/truncated table files before opening the reader\nfor table in &expected_tables {\n    let path = snapshot_dir.join(table);\n    let len = std::fs::metadata(&path)\n        .with_context(|| format!(\"missing snapshot table {path:?}\"))?\n        .len();\n    anyhow::ensure!(len > 0, \"snapshot table {table} is empty ({len} bytes)\");\n}","typeGuard":null,"tryCatchPattern":"match StateReader::open(snapshot_metadata) {\n    Err(e) if e.to_string().contains(\"No block height found\") => {\n        // a table parquet file is empty/header-only → regenerate the snapshot\n        regenerate_snapshot().await?;\n    }\n    other => other?,\n}","preventionTips":["Let snapshot generation run to completion; a killed writer leaves header-only files.","Always call the writer's close()/finalize before using a snapshot.","Validate file sizes against the metadata before opening a reader."],"tags":["rust","fuel-core","chain-config","parquet","snapshot","empty-file"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}