a-b-street/abstreet · error
Bad DistanceInterval
Error message
Bad DistanceInterval {} .. {} What it means
DistanceInterval::new_driving validates that the driving interval runs forward along a lane: end must be >= start. Driving distances must be monotonic, so a reversed interval panics at construction instead of yielding a negative-length slice.
Solutions
- Use new_walking instead if the interval may be reversed (contraflow) by design
- Check that end is measured further along the same lane than start
- Clamp or swap the distances before constructing
Example fix
// before
let d = DistanceInterval::new_driving(far, near);
// after
let d = if far < near { DistanceInterval::new_driving(far, far.max(near)) } else { DistanceInterval::new_driving(near, far) }; Defensive patterns
Strategy: validation
Validate before calling
if end >= start { let d = DistanceInterval::new_driving(start, end); } Type guard
fn valid_driving_interval(start: Distance, end: Distance) -> bool { end >= start } Try / catch
let d = std::panic::catch_unwind(|| DistanceInterval::new_driving(start, end)).ok();
Prevention
- Use new_walking for any interval that may be reversed (contraflow)
- Clamp distances against map.get_l(lane).length() before constructing
When it happens
Trigger: Calling DistanceInterval::new_driving(start, end) with end < start, typically from mixed-up along-lane distances. Note new_walking deliberately permits start > end (contraflow), so only the driving constructor panics.
Common situations: Path-following code that computes start/end distances from wrong direction of traversal; agents routed the wrong way on one-way lanes; unit confusion between lane-length fractions and absolute distances.
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
- Bad TimeInterval ..
- Can't spawn at ; it isn't that long
- Can't start at ; it's the edge of a border already
- A trip just walking from
- trying to make a crossing_state from to at . Something's…
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/b1a24d82951b4e61.
Report an issue: GitHub.
Appendix: source
Thrown at sim/src/lib.rs:538
pub fn percent_clamp_end(&self, t: Time) -> f64 {
if t > self.end {
return 1.0;
}
self.percent(t)
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]
pub(crate) struct DistanceInterval {
// TODO Private fields
pub start: Distance,
pub end: Distance,
}
impl DistanceInterval {
pub fn new_driving(start: Distance, end: Distance) -> DistanceInterval {
if end < start {
panic!("Bad DistanceInterval {} .. {}", start, end);
}
DistanceInterval { start, end }
}
pub fn new_walking(start: Distance, end: Distance) -> DistanceInterval {
// start > end is fine, might be contraflow.
DistanceInterval { start, end }
}
pub fn lerp(&self, x: f64) -> Distance {
assert!((0.0..=1.0).contains(&x));
self.start + x * (self.end - self.start)
}
pub fn length(&self) -> Distance {
(self.end - self.start).abs()
}
}View on GitHub (pinned to 0964f29315)