astrid-runtime/astrid · error
stability fixture has no interior boundary
Error message
stability fixture has no interior boundary
What it means
`sampled_boundaries` samples boundary positions from a stability fixture at configured quantiles. It drops the last byte to build the 'interior' region; if the fixture is empty or a single byte, there is no interior boundary to sample, so the function refuses rather than returning empty/garbage results.
Source
Thrown at crates/astrid-storage-chunker-evidence/src/stability.rs:143
let summary = summarize(&cases, neighborhoods.len())?;
Ok(StabilityResult {
candidate: candidate.name.clone(),
fixture_bytes: u64::try_from(base.len())?,
base_chunks: u64::try_from(original.len())?,
summary,
cases,
})
}
fn sampled_boundaries(
original: &[Chunk],
quantiles_basis_points: &[u16],
) -> Result<Vec<(u16, usize)>> {
let interior = original
.get(..original.len().saturating_sub(1))
.ok_or_else(|| anyhow::anyhow!("stability fixture has no interior boundary"))?;
if interior.is_empty() {
bail!("stability fixture has no interior boundary");
}
let mut sampled = Vec::with_capacity(quantiles_basis_points.len());
let mut previous_index = None;
for quantile in quantiles_basis_points {
if *quantile == 0 || *quantile >= 10_000 {
bail!("stability quantiles must lie strictly between zero and 10,000");
}
let index = usize::try_from(
u64::try_from(interior.len())?
.checked_mul(u64::from(*quantile))
.and_then(|value| value.checked_div(10_000))
.ok_or_else(|| anyhow::anyhow!("stability quantile overflow"))?,
)?
.min(
interior
.len()
.checked_sub(1)
.expect("the empty interior returned above"),View on GitHub (pinned to affd8760f4)
Solutions
- Replace the fixture with content of at least 2 bytes (practically, many chunk-boundary-sized bytes).
- Check the fixture file/path for truncation — verify its size on disk matches expectations.
- Skip fixtures smaller than the minimum in the caller before invoking measure_fixture.
- If a tiny fixture is intentional, guard sampled_boundaries to return an empty sample instead of erroring.
Example fix
// before let fixture: Vec<u8> = Vec::new(); // after let fixture: Vec<u8> = (0..64 * 1024).map(|i| (i % 251) as u8).collect();
Defensive patterns
Strategy: validation
Validate before calling
fn fixture_samplable(fixture: &[u8]) -> bool {
fixture.len() >= 2
} Type guard
fn is_interior_samplable(original: &[u8]) -> bool {
original.len().checked_sub(1).map(|n| n > 0).unwrap_or(false)
} Try / catch
match measure_fixture(&fixture, &quantiles) {
Err(e) if e.to_string().contains("no interior boundary") => {
eprintln!("fixture too small ({} bytes); skipping", fixture.len());
},
r => r?,
} Prevention
- Generate fixtures of at least several chunk-target-sizes in length.
- Assert fixture size at load time in test setup.
- Skip fixtures below a minimum-size threshold instead of feeding them to measure_fixture.
When it happens
Trigger: Calling `measure_fixture` with a fixture byte string of length 0 or 1, so `original.get(..len-1)` yields None (empty input) or an empty interior slice.
Common situations: A test/evidence fixture file defined as empty or one byte long; a fixture path resolving to a stub placeholder; configuration listing a fixture that was truncated to a single byte.
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
- stability quantiles must lie strictly between zero and 10,00
- stability quantiles select duplicate boundary neighborhoods
- durable capsule {} has malformed contracts pin
- refusing to seed canonical from a non-content-address contra
- timeout exceeds upper bound ({TIMEOUT_SECS_UPPER_BOUND}s)
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c18c73d567d156f5.
Report an issue: GitHub.