{"record":{"id":"04e1d036aa082a3e","repo":"block/buzz","slug":"max-objects-must-be-greater-than-zero","errorCode":null,"errorMessage":"--max-objects must be greater than zero","messagePattern":"--max-objects must be greater than zero","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-admin/src/main.rs","lineNumber":186,"sourceCode":"        Command::AddMember { pubkey, role } => cmd_add_member(pubkey, role).await,\n        Command::RemoveMember { pubkey, role } => cmd_remove_member(pubkey, role).await,\n        Command::ListMembers => cmd_list_members().await,\n        Command::ProductFeedback {\n            command: ProductFeedbackCommand::List { limit },\n        } => cmd_list_product_feedback(limit).await,\n        Command::Deletions { command } => deletions::run(command).await,\n        Command::ReconcileChannels { channel, relay_key } => {\n            reconcile_channels(channel, relay_key).await?;\n            Ok(0)\n        }\n    }\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!({","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/block/buzz/blob/ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be/crates/buzz-admin/src/main.rs#L168-L204","documentation":"The storage-snapshot command requires a positive object cap; --max-objects 0 would make the bucket-listing fold a no-op and persist an empty snapshot. The guard rejects zero explicitly after the i64 range check.","triggerScenarios":"Invoking `buzz-admin storage-snapshot --max-objects 0`. The u64 parses fine and the i64 conversion succeeds, but the `max_objects == 0` check fires.","commonSituations":"A shell script defaulting an unset variable to 0 (`--max-objects ${MAX_OBJECTS:-0}`), or a user assuming 0 means 'no limit'.","solutions":["Pass a positive value, e.g. --max-objects 1000000.","Fix scripts so an unset/empty cap variable defaults to a sane positive number instead of 0.","There is no 'unlimited' mode via 0; choose a very large positive cap if a bound is not desired."],"exampleFix":"// before\nbuzz-admin storage-snapshot --max-objects 0\n// after\nbuzz-admin storage-snapshot --max-objects 1000000","handlingStrategy":"validation","validationCode":"if max_objects == 0 {\n    return Err(\"--max-objects must be a positive integer\".into());\n}","typeGuard":"fn is_positive(v: u64) -> bool { v > 0 }","tryCatchPattern":null,"preventionTips":["Never pass 0 to mean 'unlimited' — check the CLI's documented semantics first.","In shell wrappers, use `${VAR:-1000000}` style defaults with positive values.","Add a positivity check in any script that forwards user input to --max-objects."],"tags":["cli","argument-validation","storage"],"backgroundTag":"invalid-cli-argument","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"}