a-b-street/abstreet · error
Transit route will warp from
Error message
Transit route will warp from {} to {} What it means
After collecting per-leg paths, all_paths verifies that consecutive paths are contiguous: the end of path[i] must equal the start of path[i+1]. A mismatch means the transit vehicle would teleport ("warp") between positions, so the route is rejected. This catches routes whose stop sequence is not a connected chain of drivable paths.
Solutions
- Check the two positions in the message; ensure the intermediate stop connects both legs — often the middle stop is unreachable so its leg silently deviates.
- Reorder or insert stops so the sequence forms a continuous forward chain.
- Recompute routes after any map geometry/connectivity changes.
- Fix unreachable map segments (missing connections) that make one leg's path terminate elsewhere.
Example fix
// before: route [A, C, B] where C is off the A->B corridor let stops = vec![a, c, b]; // after: order stops along the actual travel corridor let stops = vec![a, b, c];
Defensive patterns
Strategy: validation
Validate before calling
for pair in stops.windows(2) {
let req = PathRequest::vehicle(pair[0], pair[1], mode);
let path = map.pathfind(req)?;
if path.end() != next_leg_start(pair[1]) {
return Err("discontinuous stop chain".into());
}
} Try / catch
match route.all_paths(&map) {
Err(e) if e.to_string().starts_with("Transit route will warp") => {
// recompute/reorder stops based on the two positions in the message
}
other => other?,
} Prevention
- Keep stop lists sorted along the actual travel corridor.
- Recompute all transit routes after any map geometry change.
- Insert intermediate stops so legs share endpoints rather than skipping nodes.
When it happens
Trigger: create_route / create_empty_route where for some adjacent pair, pair[0].get_req().end != pair[1].get_req().start (map_model/src/objects/transit.rs:130) — e.g. the path from stop A ends at a location different from where the path to stop C begins.
Common situations: Stop lists edited out of order, stops on disconnected parts of the map after edits, or route definitions reused across different map versions whose paths changed.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Two consecutive stops are on the same road, but they travel…
- 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/77e218f05944c404.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/objects/transit.rs:130
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().start
);
}
}
Ok(paths)
}
pub fn plural_noun(&self) -> &'static str {
if self.route_type == PathConstraints::Bus {
"buses"
} else {
"trains"
}
}
}View on GitHub (pinned to 0964f29315)