astrid-runtime/astrid · error

stability measurement produced no edit cases

Error message

stability measurement produced no edit cases

What it means

summarize() aggregates boundary-survival statistics across edit cases produced by a chunker stability measurement. If the case list is empty there is nothing to summarize, so the function bails instead of producing a meaningless or divide-by-zero summary. This guards the internal invariant that measure_fixture always generates at least one edit case before summarizing.

Solutions

  1. Check that the fixture passed to measure_fixture is non-empty and large enough to generate edit cases
  2. Review the measurement configuration so at least one edit case is produced per neighborhood
  3. Guard the call site: verify cases are generated before invoking summarize, or return a descriptive error earlier

Example fix

// before
let summary = summarize(&cases, neighborhoods)?;
// after
if cases.is_empty() {
    bail!("fixture {:?} produced no edit cases; use a larger fixture", fixture_path);
}
let summary = summarize(&cases, neighborhoods)?;
Defensive patterns

Strategy: validation

Validate before calling

// rust
anyhow::ensure!(!fixture.is_empty(), "fixture must contain data for stability measurement");
// then assert generated cases before summarizing
anyhow::ensure!(!cases.is_empty(), "no edit cases generated; check measurement config");

Prevention

When it happens

Trigger: Calling measure_fixture on a fixture where the configured edit-case generation yields zero EditResult entries (e.g. an empty or too-small fixture, or a configuration that disables all edit operations), so summarize() receives an empty cases slice.

Common situations: Pointing the stability harness at a tiny or zero-byte fixture; misconfigured edit parameters (all edit probabilities zero); running measurements against fixture files that were truncated or failed to load.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/509dbd7113699e63. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-storage-chunker-evidence/src/stability.rs:319

        fixture_quantile_basis_points,
        kind,
        anchor,
        edit_offset: u64::try_from(edit.old_start)?,
        edit_bytes: u64::try_from(edit.old_end.saturating_sub(edit.old_start).max(EDIT_BYTES))?,
        boundaries_considered: considered,
        boundaries_survived: survived,
        boundary_survival_basis_points: survival_basis_points,
        identical_chunks_reused: u64::try_from(identical_chunks_reused)?,
        new_chunks: u64::try_from(edited.len().saturating_sub(identical_chunks_reused))?,
        resynchronization_bytes: first_resynchronized_start
            .map(|start| u64::try_from(start.saturating_sub(edit.new_end)))
            .transpose()?,
    })
}

fn summarize(cases: &[EditResult], neighborhoods: usize) -> Result<StabilitySummary> {
    if cases.is_empty() {
        bail!("stability measurement produced no edit cases");
    }
    let minimum_boundary_survival_basis_points = cases
        .iter()
        .map(|case| case.boundary_survival_basis_points)
        .min()
        .expect("the non-empty case set has a minimum");
    let cases_without_resynchronization = cases
        .iter()
        .filter(|case| case.resynchronization_bytes.is_none())
        .count();
    let mut distances = cases
        .iter()
        .filter_map(|case| case.resynchronization_bytes)
        .collect::<Vec<_>>();
    distances.sort_unstable();
    let resynchronization_bytes = if distances.is_empty() {
        None
    } else {

View on GitHub (pinned to affd8760f4)