a-b-street/abstreet · critical
( ) is a border, but is connected to >1 road
Error message
{} ({}) is a border, but is connected to >1 road: {:?} What it means
During map import in create_from_raw, every intersection classified as a border must connect to exactly one road. This panic fires when a border intersection is found connected to more than one road, meaning the clipping/extract-at-boundary logic produced an invalid graph that cannot be used for sim handoff at the boundary.
Solutions
- Adjust the clip polygon so each border intersection touches exactly one road (avoid cutting through junctions).
- Enlarge the extraction boundary so the problematic node becomes an interior intersection instead of a border.
- Inspect the printed orig_id OSM way links and fix or remove the offending ways in the raw map (via an edits JSON).
- Re-extract the map with the standard importer instead of hand-built RawMaps.
Example fix
// before: clip polygon corner passes through a junction, splitting one way into two segments at a border node let polygon = Polygon::rectangle(...); // too tight // after: extend the polygon outward so the junction is fully interior let polygon = polygon.get_outer_shell().simplify(...).enlarge(...);
Defensive patterns
Strategy: validation
Validate before calling
// before create_from_raw: verify every border intersection has exactly one incident road
for i in &raw.intersections {
if i.intersection_type == IntersectionType::Border {
let n = raw.roads.iter().filter(|r| r.src_i == i.id || r.dst_i == i.id).count();
if n > 1 { return Err(anyhow!("border {} has {} roads", i.id, n)); }
}
} Prevention
- Design clip polygons that avoid cutting through junctions
- Always run the standard map importer rather than hand-building RawMaps
- Log OSM way IDs of border roads when iterating on extraction boundaries
When it happens
Trigger: Calling Map::create_from_raw with RawMap whose clip polygon cuts an OSM way such that a border node retains two or more incident road segments (e.g. the boundary crosses the way twice near a junction).
Common situations: Importing an OSM extract with a badly shaped or too-small clip boundary; boundary running through an intersection; custom extractions made with external tools instead of the built-in extractor.
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
- isn't an endpoint of
- front path has 0 length
- parking lot center didn't snap to a sidewalk
- Some IndividTrip wasn't associated with a Person?!
- Giving up looking for a driving lane near
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/f0dfae29764e5a84.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/make/mod.rs:218
road.recreate_lanes(r.lane_specs_ltr.clone());
for lane in &road.lanes {
map.intersections[lane.src_i.0].outgoing_lanes.push(lane.id);
map.intersections[lane.dst_i.0].incoming_lanes.push(lane.id);
}
map.roads.push(road);
}
for i in map.intersections.iter_mut() {
if i.is_border() && i.roads.len() != 1 {
// i.orig_id may be synthetic and useless, so also print OSM links of the roads
let border_roads = i
.roads
.iter()
.map(|r| map.roads[r.0].orig_id.osm_way_id.to_string())
.collect::<Vec<_>>();
panic!(
"{} ({}) is a border, but is connected to >1 road: {:?}",
i.id, i.orig_id, border_roads
);
}
if i.control == IntersectionControl::Signalled {
let mut ok = true;
for r in &i.roads {
let road = &map.roads[r.0];
// Skip signals only connected to roads under construction or purely to control
// light rail tracks.
if road.osm_tags.is(osm::HIGHWAY, "construction") || road.is_light_rail() {
ok = false;
break;
}
// Skip signals that likely don't have correct intersection geometry
if road.trim_start == Distance::ZERO || road.trim_end == Distance::ZERO {
ok = false;
break;View on GitHub (pinned to 0964f29315)