a-b-street/abstreet · error
doesn't point to
Error message
{} doesn't point to {} What it means
This constructor builds a DirectedRoadID pointing away from intersection i, choosing Fwd if i is the source endpoint and Back if it's the destination. Panics when i is not an endpoint of the road, so no valid direction exists.
Solutions
- Ensure i comes from road.src_i or road.dst_i (or other_endpt results) before constructing.
- Fix pathfinding adjacency so expansion only uses roads incident to the intersection.
- Refresh IDs if the map was reloaded or regenerated.
Example fix
// before
let dr = DirectedRoadID { road: r.id, dir: ??? };
// after
let dr = r.DirectedRoadID(i); // only after asserting r.src_i == i || r.dst_i == i Defensive patterns
Strategy: type-guard
Type guard
fn directed_road_safe(road: &Road, i: IntersectionID) -> Option<DirectedRoadID> {
if road.src_i == i { Some(DirectedRoadID { road: road.id, dir: Direction::Fwd }) }
else if road.dst_i == i { Some(DirectedRoadID { road: road.id, dir: Direction::Back }) }
else { None }
} Prevention
- Build pathfinding expansion from true intersection adjacency
- Never reuse directed-road constructions across map versions
- Assert endpoint relation in debug builds before constructing
When it happens
Trigger: Calling road.DirectedRoadID(i) (the constructor) with an IntersectionID that is neither road.src_i nor road.dst_i — e.g. from pathfinding expansion over wrong adjacency lists.
Common situations: Custom routing algorithms expanding directed roads from intersections; using intersection IDs from a different road after ID staleness.
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
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/22cd9dbb6a6ee793.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/objects/road.rs:545
/// Many roads wind up with almost no length, due to their representation in OpenStreetMap. In
/// reality, these segments are likely located within the interior of an intersection. This
/// method uses a hardcoded threshold to detect these cases.
pub fn is_extremely_short(&self) -> bool {
self.length() < Distance::meters(2.0)
}
/// Get the DirectedRoadID pointing to the intersection. Panics if the intersection isn't an
/// endpoint.
pub fn directed_id_from(&self, i: IntersectionID) -> DirectedRoadID {
DirectedRoadID {
road: self.id,
dir: if self.src_i == i {
Direction::Fwd
} else if self.dst_i == i {
Direction::Back
} else {
panic!("{} doesn't point to {}", self.id, i);
},
}
}
/// Get the DirectedRoadID pointing from the intersection. Panics if the intersection isn't an
/// endpoint.
pub fn directed_id_to(&self, i: IntersectionID) -> DirectedRoadID {
let mut id = self.directed_id_from(i);
id.dir = id.dir.opposite();
id
}
pub(crate) fn recreate_lanes(&mut self, lane_specs_ltr: Vec<LaneSpec>) {
self.lanes.clear();
let total_width = lane_specs_ltr.iter().map(|x| x.width).sum();
let mut width_so_far = Distance::ZERO;View on GitHub (pinned to 0964f29315)