a-b-street/abstreet · error
Two consecutive stops are on the same road, but they travel…
Error message
Two consecutive stops are on the same road, but they travel backwards: {} What it means
Transit route construction walks consecutive stop pairs and builds a path request for each. If two consecutive stops lie on the same road but the requested trip goes backwards along it (start.dist_along() > end.dist_along()), no forward path exists, so all_paths bails. The library refuses to synthesize U-turn or reversed travel for transit vehicles.
Solutions
- Reorder or remove the offending stop pair in the transit route so travel proceeds forward along the road.
- Move one of the stops to the opposite side / correctly directed road in the map editor.
- Split the route into two routes at the turnaround point, inserting a loop via different roads.
- Rebuild the map so the road is split at the stop, giving each stop its own correctly directed road.
Example fix
// before: stops A (dist 900) then B (dist 100) on same road let route = TransitRoute::create_route(&map, vec![stop_a, stop_b])?; // after: place stop B on the opposite-direction road or reorder let route = TransitRoute::create_route(&map, vec![stop_b_opposite_dir, stop_a])?;
Defensive patterns
Strategy: validation
Validate before calling
for pair in stops.windows(2) {
if pair[0].lane().road == pair[1].lane().road
&& pair[0].dist_along() > pair[1].dist_along() {
return Err(format!("backwards pair on road {}", pair[0].lane().road));
}
} Try / catch
match TransitRoute::create_route(&map, stops) {
Err(e) if e.to_string().starts_with("Two consecutive stops") => {
// fix stop ordering/placement and retry
}
other => other?,
} Prevention
- Assign transit stops to lanes matching the travel direction of the route.
- Validate route stop ordering against road geometry before route creation.
- Split looping routes at turnarounds instead of reversing along the same road.
When it happens
Trigger: Creating a transit route (create_route / create_empty_route) where stop N and stop N+1 are on the same road but the vehicle must travel in reverse direction of the road's lane ordering, i.e. req.start.dist_along() > req.end.dist_along() (map_model/src/objects/transit.rs:115).
Common situations: Transit data (GTFS-like imports) where stops are placed by position rather than driving direction, or a route loops back along the same road; also bidirectional stops auto-assigned to the wrong side of the street.
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
- Transit route will warp from
- Empty path between stops
- can't find
- Giving up looking for a driving lane near
- No transit route from
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/cb740297ec46ce2b.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/objects/transit.rs:115
// Drive to the end of the lane with the last stop
steps.push(PathRequest::vehicle(
last_stop_pos,
Position::end(last_stop_pos.lane(), map),
self.route_type,
));
}
steps
}
/// Entry i is the path to drive to stop i. The very last entry is to drive from the last step
/// to the place where the vehicle vanishes.
pub fn all_paths(&self, map: &Map) -> Result<Vec<Path>> {
let mut paths = Vec::new();
for req in self.all_path_requests(map) {
if req.start.lane().road == req.end.lane().road
&& req.start.dist_along() > req.end.dist_along()
{
bail!(
"Two consecutive stops are on the same road, but they travel backwards: {}",
req
);
}
let path = map.pathfind(req)?;
if path.is_empty() {
bail!("Empty path between stops: {}", path.get_req());
}
paths.push(path);
}
for pair in paths.windows(2) {
if pair[0].get_req().end != pair[1].get_req().start {
bail!(
"Transit route will warp from {} to {}",
pair[0].get_req().end,
pair[1].get_req().startView on GitHub (pinned to 0964f29315)