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
- Deduplicate samples by seed before calling compare (keep the last or first occurrence).
- Fix the seed generation to produce unique seeds (e.g. unique range or counter-based).
- 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
- Generate seeds from a monotonic counter or checked unique range
- Deduplicate merged sample sets by seed before comparison
- Unit-test the seed generator for uniqueness
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
- genre references collapsed into a generic style; distinct…
- samples cannot be empty
- scores must be finite and between 0 and 1
- -32602
- a claim token is required
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)