{"record":{"id":"884f32a2615853f0","repo":"block/buzz","slug":"buzz-storage-snapshot-code-sha-must-contain-1-to-128-bytes","errorCode":null,"errorMessage":"BUZZ_STORAGE_SNAPSHOT_CODE_SHA must contain 1 to 128 bytes","messagePattern":"BUZZ_STORAGE_SNAPSHOT_CODE_SHA must contain 1 to 128 bytes","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-admin/src/main.rs","lineNumber":197,"sourceCode":"    }\n}\n\nasync fn cmd_storage_snapshot(max_objects: u64) -> Result<i32> {\n    let max_objects_db = i64::try_from(max_objects)\n        .map_err(|_| anyhow::anyhow!(\"--max-objects must be at most {}\", i64::MAX))?;\n    if max_objects == 0 {\n        return Err(anyhow::anyhow!(\"--max-objects must be greater than zero\"));\n    }\n\n    let db = connect_db().await?;\n    let mut leader = db.try_lock_storage_accounting().await?.ok_or_else(|| {\n        anyhow::anyhow!(\"another storage-snapshot worker already holds the lease\")\n    })?;\n    let storage = Arc::new(MediaStorage::new(&storage_config_from_env()?)?);\n    let code_sha =\n        std::env::var(\"BUZZ_STORAGE_SNAPSHOT_CODE_SHA\").unwrap_or_else(|_| \"unknown\".to_string());\n    if code_sha.is_empty() || code_sha.len() > 128 {\n        return Err(anyhow::anyhow!(\n            \"BUZZ_STORAGE_SNAPSHOT_CODE_SHA must contain 1 to 128 bytes\"\n        ));\n    }\n\n    println!(\n        \"{}\",\n        serde_json::json!({\n            \"event\": \"storage_snapshot_started\",\n            \"max_objects\": max_objects,\n            \"code_sha\": code_sha,\n        })\n    );\n    let run_started = Instant::now();\n    let listed_objects = Arc::new(AtomicU64::new(0));\n    let fold = buzz_media::fold_bucket_listing(max_objects, move |token| {\n        let storage = Arc::clone(&storage);\n        let listed_objects = Arc::clone(&listed_objects);\n        async move {","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/block/buzz/blob/ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be/crates/buzz-admin/src/main.rs#L179-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set BUZZ_STORAGE_SNAPSHOT_CODE_SHA to a 1–128 byte identifier, e.g. the git commit SHA (git rev-parse HEAD).","If the SHA is genuinely unavailable, unset the variable entirely so the default \"unknown\" applies instead of exporting an empty string.","Trim the value in the CI step that produces it (e.g. take only the first 40/64 hex chars)."],"exampleFix":"// before (CI)\nexport BUZZ_STORAGE_SNAPSHOT_CODE_SHA=\"\"\nbuzz-admin storage-snapshot --max-objects 1000000\n// after\nexport BUZZ_STORAGE_SNAPSHOT_CODE_SHA=\"$(git rev-parse HEAD)\"\nbuzz-admin storage-snapshot --max-objects 1000000","handlingStrategy":"validation","validationCode":"match std::env::var(\"BUZZ_STORAGE_SNAPSHOT_CODE_SHA\") {\n    Ok(v) if v.is_empty() || v.len() > 128 => panic!(\"CODE_SHA must be 1-128 bytes\"),\n    Ok(_) | Err(_) => {} // set-and-valid, or unset (defaults to \"unknown\")\n}","typeGuard":"fn valid_code_sha(v: Option<&str>) -> bool {\n    matches!(v, None) || matches!(v, Some(s) if !s.is_empty() && s.len() <= 128)\n}","tryCatchPattern":null,"preventionTips":["In CI, guard the export: only set the var when the SHA is non-empty and short.","Prefer leaving the var unset over exporting an empty string — unset is the safe default (\"unknown\").","Store a single short SHA (40–64 hex chars), never build manifests or concatenated identifiers."],"tags":["environment","configuration","validation","storage"],"backgroundTag":"invalid-env-var-value","analyzedSha":"ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be","analyzedAt":"2026-09-20T04:38:17.397Z","contentChangedAt":"2026-09-20T04:38:17.397Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}