a-b-street/abstreet · error
Negative dist_ahead?!
Error message
Negative dist_ahead?! {} What it means
Path::exact_slice slices a path to a requested distance ahead; a negative dist_ahead is meaningless, so the method panics with "Negative dist_ahead?!". Zero distance is handled separately as a normal Err. This is a caller contract check: distances passed for slicing must be non-negative.
Solutions
- Clamp the distance before calling: Some(d.max(Distance::ZERO))
- Skip the slice call when the computed remaining distance is <= zero
- Fix the upstream arithmetic that produced the negative distance (usually a subtraction without a floor)
- Pass None when you do not need a bounded slice
Example fix
// before
let slice = path.exact_slice(map, start, Some(remaining))?,;
// after
let d = remaining.max(Distance::ZERO);
let slice = if d == Distance::ZERO { None } else { Some(path.exact_slice(map, start, Some(d))?) }; Defensive patterns
Strategy: validation
Validate before calling
fn safe_dist_ahead(d: Distance) -> Option<Distance> {
if d < Distance::ZERO { None } else { Some(d) }
} Type guard
fn non_negative(d: Distance) -> Option<Distance> {
if d >= Distance::ZERO { Some(d) } else { None }
} Try / catch
// method returns Result and only panics on negatives; clamp first:
match path.exact_slice(map, start, Some(d.max(Distance::ZERO))) {
Ok(slice) => handle(slice),
Err(e) => handle_zero_slice(e), // catches "0 dist ahead" via bail!
} Prevention
- Clamp any computed lookahead distance with max(Distance::ZERO)
- Handle the zero-distance Err case explicitly (it returns Err, not panic)
- Avoid subtraction-based distances without a floor
- Pass None when the slice bound is not needed
When it happens
Trigger: Calling exact_slice with dist_ahead = Some(negative Distance), typically from an arithmetic result that underflowed (e.g. remaining_distance - dist_already_traveled going below zero).
Common situations: Slice/trim logic that computes the lookahead distance by subtraction and can go negative at path endpoints; sim agents requesting a slice past the end of a route with signed math.
Related errors
- PathConstraints::from_lt
- expected turn, but found
- modify_step broke total_length, it's now
- Empty path
- pathfind() returned path that warps
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/7c298c137e047620.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/pathfind/v1.rs:53
pub fn as_lane(&self) -> LaneID {
self.as_traversable().as_lane()
}
pub fn as_turn(&self) -> TurnID {
self.as_traversable().as_turn()
}
// start is relative to the start of the actual geometry -- so from the lane's real start for
// ContraflowLane.
fn exact_slice(
&self,
map: &Map,
start: Distance,
dist_ahead: Option<Distance>,
) -> Result<PolyLine> {
if let Some(d) = dist_ahead {
if d < Distance::ZERO {
panic!("Negative dist_ahead?! {}", d);
}
if d == Distance::ZERO {
bail!("0 dist ahead for slice");
}
}
match self {
PathStep::Lane(id) => {
let pts = &map.get_l(*id).lane_center_pts;
if let Some(d) = dist_ahead {
pts.maybe_exact_slice(start, start + d)
} else {
pts.maybe_exact_slice(start, pts.length())
}
}
PathStep::ContraflowLane(id) => {
let pts = map.get_l(*id).lane_center_pts.reversed();
let reversed_start = pts.length() - start;View on GitHub (pinned to 0964f29315)