block/buzz · error · anyhow::Error

BUZZ_STORAGE_SNAPSHOT_CODE_SHA must contain 1 to 128 bytes

Error message

BUZZ_STORAGE_SNAPSHOT_CODE_SHA must contain 1 to 128 bytes

What it means

The snapshot run records the code version that produced it via the BUZZ_STORAGE_SNAPSHOT_CODE_SHA environment variable; save_snapshot persists it alongside the data. The value must be non-empty and at most 128 bytes. Note the env var defaults to the literal string "unknown" when unset — this error fires only when the var is set to an empty or over-long value.

Solutions

  1. Set BUZZ_STORAGE_SNAPSHOT_CODE_SHA to a 1–128 byte identifier, e.g. the git commit SHA (git rev-parse HEAD).
  2. If the SHA is genuinely unavailable, unset the variable entirely so the default "unknown" applies instead of exporting an empty string.
  3. Trim the value in the CI step that produces it (e.g. take only the first 40/64 hex chars).

Example fix

// before (CI)
export BUZZ_STORAGE_SNAPSHOT_CODE_SHA=""
buzz-admin storage-snapshot --max-objects 1000000
// after
export BUZZ_STORAGE_SNAPSHOT_CODE_SHA="$(git rev-parse HEAD)"
buzz-admin storage-snapshot --max-objects 1000000
Defensive patterns

Strategy: validation

Validate before calling

match std::env::var("BUZZ_STORAGE_SNAPSHOT_CODE_SHA") {
    Ok(v) if v.is_empty() || v.len() > 128 => panic!("CODE_SHA must be 1-128 bytes"),
    Ok(_) | Err(_) => {} // set-and-valid, or unset (defaults to "unknown")
}

Type guard

fn valid_code_sha(v: Option<&str>) -> bool {
    matches!(v, None) || matches!(v, Some(s) if !s.is_empty() && s.len() <= 128)
}

Prevention

When it happens

Trigger: Setting BUZZ_STORAGE_SNAPSHOT_CODE_SHA="" (empty) or a value longer than 128 bytes (e.g. pasting a full multi-line build manifest, a PEM blob, or a concatenated hash list) before running storage-snapshot.

Common situations: CI exporting an empty variable when the git SHA is unavailable, or accidentally exporting a wrong/too-long build identifier; unset is safe (defaults to "unknown") but explicitly empty is not.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-09-20). Data as JSON: /api/errors/884f32a2615853f0. Report an issue: GitHub.

Appendix: source

Thrown at crates/buzz-admin/src/main.rs:197

    }
}

async fn cmd_storage_snapshot(max_objects: u64) -> Result<i32> {
    let max_objects_db = i64::try_from(max_objects)
        .map_err(|_| anyhow::anyhow!("--max-objects must be at most {}", i64::MAX))?;
    if max_objects == 0 {
        return Err(anyhow::anyhow!("--max-objects must be greater than zero"));
    }

    let db = connect_db().await?;
    let mut leader = db.try_lock_storage_accounting().await?.ok_or_else(|| {
        anyhow::anyhow!("another storage-snapshot worker already holds the lease")
    })?;
    let storage = Arc::new(MediaStorage::new(&storage_config_from_env()?)?);
    let code_sha =
        std::env::var("BUZZ_STORAGE_SNAPSHOT_CODE_SHA").unwrap_or_else(|_| "unknown".to_string());
    if code_sha.is_empty() || code_sha.len() > 128 {
        return Err(anyhow::anyhow!(
            "BUZZ_STORAGE_SNAPSHOT_CODE_SHA must contain 1 to 128 bytes"
        ));
    }

    println!(
        "{}",
        serde_json::json!({
            "event": "storage_snapshot_started",
            "max_objects": max_objects,
            "code_sha": code_sha,
        })
    );
    let run_started = Instant::now();
    let listed_objects = Arc::new(AtomicU64::new(0));
    let fold = buzz_media::fold_bucket_listing(max_objects, move |token| {
        let storage = Arc::clone(&storage);
        let listed_objects = Arc::clone(&listed_objects);
        async move {

View on GitHub (pinned to ef2aa1ae38)