affaan-m/ECC · error
minimum samples must be positive
Error message
minimum samples must be positive
What it means
`PromotionPolicy::validate` checks that `min_samples` is at least 1 before any statistical comparison. A policy requiring zero samples is meaningless — no result could ever fail the threshold — so it is rejected as a configuration mistake.
Solutions
- Set `min_samples` to a positive value (e.g. 30 for a reasonable paired-comparison baseline) before calling `compare`
- Validate the policy right after deserialization and fail with a clear config error
- Guard computed values with `min_samples.max(1)`
Example fix
// before
let policy = PromotionPolicy { min_samples: 0, .. };
let comparison = policy.compare(&samples)?;
// after
let policy = PromotionPolicy { min_samples: 30, .. };
let comparison = policy.compare(&samples)?; Defensive patterns
Strategy: validation
Validate before calling
fn policy_is_valid(min_samples: usize) -> bool {
min_samples > 0
} Try / catch
match policy.compare(&samples) {
Ok(comparison) => comparison,
Err(e) if e.to_string().contains("minimum samples must be positive") => {
eprintln!("PromotionPolicy misconfigured: {e}");
// fall back to a sane default policy
PromotionPolicy { min_samples: 30, ..policy }.compare(&samples)?
}
Err(e) => return Err(e),
} Prevention
- Validate PromotionPolicy immediately after deserialization, before use
- Provide a `Default` with min_samples >= 1 and never hand-roll a zero default
- Treat 0 in config as 'unset' and substitute a documented default
When it happens
Trigger: Constructing a `PromotionPolicy` with `min_samples: 0` (explicitly or via `Default`/partial builder) and then calling `compare` (or `validate` directly) on a sample slice.
Common situations: Deserializing a policy from JSON/TOML where min_samples defaulted to 0; a computed `min_samples` that underflowed; users confusing 'minimum extra samples' with total sample count.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- application config exceeds local size limit
- Asset request_id/modality does not match the bundle
- at least one genre spec is required
- bundle collections must be lists
- candidate configuration exceeds 1 MiB
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/db7709b7ee9be4bd.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/harness_eval.rs:508
pub min_mean_delta: f64,
pub min_win_rate: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Comparison {
pub passed: bool,
pub sample_count: usize,
pub candidate_mean: f64,
pub baseline_mean: f64,
pub mean_delta: f64,
pub win_rate: f64,
pub failures: Vec<String>,
}
impl PromotionPolicy {
pub fn validate(self) -> Result<()> {
if self.min_samples == 0 {
bail!("minimum samples must be positive");
}
if !self.min_mean_delta.is_finite() {
bail!("minimum mean delta must be finite");
}
if !self.min_win_rate.is_finite() || !(0.0..=1.0).contains(&self.min_win_rate) {
bail!("minimum win rate must be between 0 and 1");
}
Ok(())
}
pub fn compare(self, samples: &[PairedSample]) -> Result<Comparison> {
self.validate()?;
if samples.is_empty() {
bail!("samples cannot be empty");
}
if samples
.iter()
.map(|sample| sample.seed)View on GitHub (pinned to 8321021c54)