affaan-m/ECC · error

sample seeds must be unique

Error message

sample seeds must be unique

What it means

`compare` requires every `PairedSample` to carry a distinct `seed`. Duplicate seeds would double-count the same evaluation case in the mean, delta, and win-rate statistics, silently skewing the comparison. The function collects all seeds into a `BTreeSet` and bails when the set size differs from the slice length.

Solutions

  1. Deduplicate samples by seed before calling compare (keep the last or first occurrence).
  2. Fix the seed generation to produce unique seeds (e.g. unique range or counter-based).
  3. If duplicates represent legitimate repeats, aggregate them into a single PairedSample (e.g. average) before comparing.

Example fix

// before
evaluator.compare(&samples)?;
// after
let mut seen = std::collections::BTreeSet::new();
samples.retain(|s| seen.insert(s.seed));
evaluator.compare(&samples)?;
Defensive patterns

Strategy: validation

Validate before calling

let unique: std::collections::BTreeSet<_> = samples.iter().map(|s| s.seed).collect();
anyhow::ensure!(unique.len() == samples.len(), "duplicate seeds in samples");

Try / catch

match evaluator.compare(&samples) {
    Ok(c) => c,
    Err(e) if e.to_string().contains("seeds must be unique") => {
        eprintln!("Deduplicate samples by seed and retry");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `compare` with two or more `PairedSample` values whose `seed` field is identical (e.g. samples generated from the same RNG seed).

Common situations: A seed generator loop that reuses a constant or a narrow range, samples re-generated for retried runs without advancing the seed, or merging sample lists from two runs that overlapped in seeds.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/0e79294b52557d83. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/harness_eval.rs:531

        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)
            .collect::<BTreeSet<_>>()
            .len()
            != samples.len()
        {
            bail!("sample seeds must be unique");
        }
        if samples.iter().any(|s| {
            !s.candidate_score.is_finite()
                || !s.baseline_score.is_finite()
                || !(0.0..=1.0).contains(&s.candidate_score)
                || !(0.0..=1.0).contains(&s.baseline_score)
        }) {
            bail!("scores must be finite and between 0 and 1");
        }
        let count = samples.len();
        let candidate_mean = samples.iter().map(|s| s.candidate_score).sum::<f64>() / count as f64;
        let baseline_mean = samples.iter().map(|s| s.baseline_score).sum::<f64>() / count as f64;
        let mean_delta = candidate_mean - baseline_mean;
        let win_rate = samples
            .iter()
            .filter(|s| s.candidate_score > s.baseline_score)
            .count() as f64
            / count as f64;

View on GitHub (pinned to 8321021c54)