a-b-street/abstreet · error
Some path does illegal uber-turn
Error message
Some path does illegal uber-turn: {} -> {} -> {} What it means
validate_restrictions verifies that a produced driving path does not perform a 'complicated turn restriction' banned on the map: going from road l1 via road l2 into road l3 where the origin road lists (dont_via, dont_to) in complicated_turn_restrictions. When the pathfinder emits such an illegal triple turn, Path::new panics. It guards the pathfinding cost function against ignoring turn restrictions.
Solutions
- Verify the map's complicated_turn_restrictions are correctly encoded and that the pathfind graph applies them as edge penalties or exclusions
- If a restriction was added by a recent edit, confirm the restriction is intentional and regenerate the map
- Debug pathfind v1 to ensure restricted transitions are removed from the graph for driving requests
- Report upstream with the map and route if it occurs on unedited maps
Example fix
// before
// pathfinder graph omitted complicated turn restrictions
graph.add_edge(from, via_to, cost);
// after
if from.complicated_turn_restrictions.contains(&(via, to)) {
continue; // skip forbidden uber-turn transition
}
graph.add_edge(from, via_to, cost); Defensive patterns
Strategy: validation
Validate before calling
fn violates_restriction(map: &Map, steps: &[PathStep]) -> bool {
steps.windows(5).any(|t| matches!(
(t[0], t[2], t[4]),
(PathStep::Lane(l1), PathStep::Lane(l2), PathStep::Lane(l3))
if map.get_parent(l1).complicated_turn_restrictions
.contains(&(l2.road, l3.road))
))
} Prevention
- After editing turn restrictions, re-run a few driving paths through the affected area
- Ensure uber-turn restrictions are encoded in the pathfind graph, not just map data
- Keep map imports and restriction data in sync
When it happens
Trigger: Path::new called on a driving path whose step sequence crosses a road pair (via, to) forbidden by from.complicated_turn_restrictions, typically when the pathfind graph failed to encode uber-turn restrictions after a map edit or import change.
Common situations: Hit when editing turn restrictions in the map editor, importing OSM data with complex no-U-turn style restrictions, or modifying the pathfind v1 graph edge construction.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- PathConstraints::from_lt
- Negative dist_ahead?!
- expected turn, but found
- modify_step broke total_length, it's now
- Empty path
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/dce65058b6aabecc.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/pathfind/v1.rs:803
"pathfind() returned path that warps {} from {:?} to {:?}",
len, pair[0], pair[1]
);
}
}
}
fn validate_restrictions(map: &Map, steps: &[PathStep]) {
for triple in steps.windows(5) {
if let (PathStep::Lane(l1), PathStep::Lane(l2), PathStep::Lane(l3)) =
(triple[0], triple[2], triple[4])
{
let from = map.get_parent(l1);
let via = l2.road;
let to = l3.road;
for (dont_via, dont_to) in &from.complicated_turn_restrictions {
if via == *dont_via && to == *dont_to {
panic!(
"Some path does illegal uber-turn: {} -> {} -> {}",
l1, l2, l3
);
}
}
}
}
}
fn validate_zones(map: &Map, steps: &[PathStep], req: &PathRequest) {
let z1 = map.get_parent(req.start.lane()).get_zone(map);
let z2 = map.get_parent(req.end.lane()).get_zone(map);
for step in steps {
if let PathStep::Turn(t) | PathStep::ContraflowTurn(t) = step {
if map
.get_parent(t.src)
.access_restrictionsView on GitHub (pinned to 0964f29315)