facebook/flow · error · std::io::Error

hh_load_heap: invalid shard count

Error message

hh_load_heap: invalid shard count

What it means

After the magic check, read_heap_with_file_table validates the header's file_shard_count and haste_module_shard_count against GC_MAP_SHARDS compiled into this build; both must match exactly. A mismatch returns ErrorKind::InvalidData "hh_load_heap: invalid shard count" — the file was written by a build with a different sharding layout, so its shard layout cannot be interpreted.

Source

Thrown at rust_port/crates/flow_heap/src/transaction.rs:1274

    }

    pub(crate) fn read_heap_with_file_table(
        reader: &mut impl Read,
        files: Arc<Vec<FileKey>>,
    ) -> std::io::Result<CommittedHeapData> {
        let header: SerializedHeapHeader = decode_from_reader(reader)?;
        if header.magic != HEAP_MAGIC_RUST_SHARDED_LOCAL_INDEXED_LZ4
            && header.magic != HEAP_MAGIC_RUST_SHARDED_INDEXED_LZ4_EXTERNAL_FILES
        {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "hh_load_heap: invalid magic number",
            ));
        }
        if header.file_shard_count != GC_MAP_SHARDS as u64
            || header.haste_module_shard_count != GC_MAP_SHARDS as u64
        {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "hh_load_heap: invalid shard count",
            ));
        }
        let files = if header.magic == HEAP_MAGIC_RUST_SHARDED_INDEXED_LZ4_EXTERNAL_FILES {
            Some(files)
        } else {
            None
        };
        Self::read_heap_shards(reader, files)
    }

    fn read_heap_shards(
        reader: &mut impl Read,
        external_files: Option<Arc<Vec<FileKey>>>,
    ) -> std::io::Result<CommittedHeapData> {
        let mut file_shards = Vec::with_capacity(GC_MAP_SHARDS);
        for _ in 0..GC_MAP_SHARDS {

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Delete the saved heap/saved-state artifacts and rebuild from sources.
  2. Ensure one consistent Flow version writes and reads the saved state (check PATH, CI caches, bundled copies).
  3. If rebuilding does not fix it, verify the saved-state directory is writable and not modified by another tool.

Example fix

# before: shard layout from a different build
flow check

# after: regenerate saved state with the current build
rm -rf .flow-saved-state   # or your configured saved-state directory
flow check
Defensive patterns

Strategy: fallback

Type guard

fn is_invalid_shard_count(e: &std::io::Error) -> bool {
    e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("invalid shard count")
}

Try / catch

On InvalidData 'invalid shard count', regenerate the saved heap from sources (delete saved state and retry). This is writer/reader format skew — the bytes cannot be repaired in place.

Prevention

When it happens

Trigger: Loading a heap whose header was written by a Flow build compiled with a different GC_MAP_SHARDS value (format revision between writer and reader), or a hand-corrupted header where the magic happened to match but counts do not.

Common situations: Downgrading or upgrading Flow while keeping saved state; a heap file partially rewritten by a crashed save so the header is inconsistent with the body.

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/e2c0770c43dde7be. Report an issue: GitHub.