a-b-street/abstreet · error

get_step_at_dist_along has leftover distance of

Error message

get_step_at_dist_along has leftover distance of {}

What it means

get_step_at_dist_along walks a PathV1's steps, subtracting each step's crossed distance until the requested dist_along falls within a step. If the loop exhausts all steps and dist_along is still > 0, the requested distance lies beyond the path's total length, so it bails with the leftover amount. This is effectively an out-of-bounds distance lookup.

Solutions

  1. Clamp dist_along to path.total_length() (minus epsilon) before calling.
  2. When leftover distance remains after the last step, end the trip or request a new path for the remainder.
  3. Use dist_along = dist_along.min(self.total_length()) instead of raw values.
  4. Audit callers that accumulate distance across ticks so they stop at path completion.

Example fix

// before
let step = path.get_step_at_dist_along(&map, dist)?;
// after
let dist = dist.min(path.total_length() - Distance::EPSILON);
let step = path.get_step_at_dist_along(&map, dist)?;
Defensive patterns

Strategy: validation

Validate before calling

let clamped = dist.min(path.total_length() - Distance::EPSILON);
assert!(clamped <= path.total_length());
let step = path.get_step_at_dist_along(&map, clamped)?;

Try / catch

match path.get_step_at_dist_along(&map, dist) {
    Err(e) if e.to_string().starts_with("get_step_at_dist_along has leftover") => {
        // distance beyond path end: finish the trip or fetch a new path
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling PathV1::get_step_at_dist_along with dist_along greater than the path's total length (map_model/src/pathfind/v1.rs:556), e.g. extrapolating an agent's position past the path end.

Common situations: Simulation ticks stepping agents farther than the remaining path length; off-by-one after slicing paths; using an unclamped distance from an animation/timeline.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/708e05923f9111c3. Report an issue: GitHub.

Appendix: source

Thrown at map_model/src/pathfind/v1.rs:556

            };
            if from < to {
                gain += to - from;
            } else {
                loss += from - to;
            }
        }
        (gain, loss)
    }

    pub fn get_step_at_dist_along(&self, map: &Map, mut dist_along: Distance) -> Result<PathStep> {
        for step in &self.steps {
            let dist_here = self.dist_crossed_from_step(map, step);
            if dist_along <= dist_here {
                return Ok(*step);
            }
            dist_along -= dist_here;
        }
        bail!(
            "get_step_at_dist_along has leftover distance of {}",
            dist_along
        );
    }

    pub fn crosses_road(&self, r: RoadID) -> bool {
        for step in &self.steps {
            if let PathStep::Lane(l) | PathStep::ContraflowLane(l) = step {
                if l.road == r {
                    return true;
                }
            }
        }
        false
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]

View on GitHub (pinned to 0964f29315)