{"record":{"id":"f0dfae29764e5a84","repo":"a-b-street/abstreet","slug":"is-a-border-but-is-connected-to-1-road","errorCode":null,"errorMessage":"{} ({}) is a border, but is connected to >1 road: {:?}","messagePattern":"(.+?) \\((.+?)\\) is a border, but is connected to >1 road: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"map_model/src/make/mod.rs","lineNumber":218,"sourceCode":"\n            road.recreate_lanes(r.lane_specs_ltr.clone());\n            for lane in &road.lanes {\n                map.intersections[lane.src_i.0].outgoing_lanes.push(lane.id);\n                map.intersections[lane.dst_i.0].incoming_lanes.push(lane.id);\n            }\n\n            map.roads.push(road);\n        }\n\n        for i in map.intersections.iter_mut() {\n            if i.is_border() && i.roads.len() != 1 {\n                // i.orig_id may be synthetic and useless, so also print OSM links of the roads\n                let border_roads = i\n                    .roads\n                    .iter()\n                    .map(|r| map.roads[r.0].orig_id.osm_way_id.to_string())\n                    .collect::<Vec<_>>();\n                panic!(\n                    \"{} ({}) is a border, but is connected to >1 road: {:?}\",\n                    i.id, i.orig_id, border_roads\n                );\n            }\n            if i.control == IntersectionControl::Signalled {\n                let mut ok = true;\n                for r in &i.roads {\n                    let road = &map.roads[r.0];\n                    // Skip signals only connected to roads under construction or purely to control\n                    // light rail tracks.\n                    if road.osm_tags.is(osm::HIGHWAY, \"construction\") || road.is_light_rail() {\n                        ok = false;\n                        break;\n                    }\n                    // Skip signals that likely don't have correct intersection geometry\n                    if road.trim_start == Distance::ZERO || road.trim_end == Distance::ZERO {\n                        ok = false;\n                        break;","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/make/mod.rs#L200-L236","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before: clip polygon corner passes through a junction, splitting one way into two segments at a border node\nlet polygon = Polygon::rectangle(...); // too tight\n// after: extend the polygon outward so the junction is fully interior\nlet polygon = polygon.get_outer_shell().simplify(...).enlarge(...);","handlingStrategy":"validation","validationCode":"// before create_from_raw: verify every border intersection has exactly one incident road\nfor i in &raw.intersections {\n    if i.intersection_type == IntersectionType::Border {\n        let n = raw.roads.iter().filter(|r| r.src_i == i.id || r.dst_i == i.id).count();\n        if n > 1 { return Err(anyhow!(\"border {} has {} roads\", i.id, n)); }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["map-import","osm","invariant","geometry"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}