{"record":{"id":"81a71896178bb502","repo":"a-b-street/abstreet","slug":"hit-the-map-boundary-at","errorCode":null,"errorMessage":"hit the map boundary at {}","messagePattern":"hit the map boundary at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"blockfinding/src/lib.rs","lineNumber":72,"sourceCode":"\n        // We may start on a loop road on the \"inner\" direction\n        {\n            let start_r = map.get_parent(start);\n            if start_r.src_i == start_r.dst_i {\n                let i = map.get_i(start_r.src_i);\n                if !i.get_road_sides_sorted(map).contains(&start_road_side) {\n                    bail!(\"Starting on inner piece of a loop road\");\n                }\n            }\n        }\n\n        // We need to track which side of the road we're at, but also which direction we're facing\n        let mut current_road_side = start_road_side;\n        let mut current_intersection = map.get_l(start).dst_i;\n        loop {\n            let i = map.get_i(current_intersection);\n            if i.is_border() {\n                bail!(\"hit the map boundary at {}\", i.orig_id);\n            }\n            let mut sorted_roads = i.get_road_sides_sorted(map);\n            sorted_roads.retain(|id| !skip.contains(&id.road));\n\n            let idx = sorted_roads\n                .iter()\n                .position(|x| *x == current_road_side)\n                .unwrap() as isize;\n            // Do we go clockwise or counter-clockwise around the intersection? Well, unless we're\n            // at a dead-end, we want to avoid the other side of the same road.\n            let mut next = *wraparound_get(&sorted_roads, idx + 1);\n            assert_ne!(next, current_road_side);\n            if next.road == current_road_side.road {\n                next = *wraparound_get(&sorted_roads, idx - 1);\n                assert_ne!(next, current_road_side);\n                if next.road == current_road_side.road {\n                    if sorted_roads.len() != 2 {\n                        bail!(\"Looped back on the same road, but not at a dead-end\");","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/blockfinding/src/lib.rs#L54-L90","documentation":"While walking the perimeter intersection by intersection, single_block reached a border intersection on the edge of the map. A block perimeter cannot be closed there, so tracing aborts and reports the boundary intersection's original OSM ID. This is expected behavior — perimeters touching the map edge are simply not produced.","triggerScenarios":"Any single_block call whose trace path reaches an intersection where is_border() is true — i.e. the block being traced touches the clipped edge of the imported map.","commonSituations":"Blocks adjacent to the boundary of a downloaded/clipped OSM extract; running blockfinding on small map areas cut out of a larger city; maps missing water/park boundary clipping.","solutions":["Accept the failure and skip blocks that touch the map boundary (find_blocks treats these as non-errors by design).","Import a larger map area so the blocks of interest don't touch the border.","Add boundary roads to the `skip` set so traces route around the border."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let dst_i = map.get_l(start).dst_i;\nif map.get_i(dst_i).is_border() { /* start leads straight to boundary; skip this block */ }","typeGuard":null,"tryCatchPattern":"match Perimeter::single_block(map, start, &skip) {\n    Ok(p) => blocks.push(p),\n    Err(e) if e.to_string().starts_with(\"hit the map boundary\") => {}, // expected, skip block\n    Err(e) => return Err(e),\n}","preventionTips":["Treat boundary failures as expected in blockfinding and filter them from real errors.","Import a larger map extent if you need blocks near the current edge."],"tags":["map-boundary","perimeter-tracing"],"backgroundTag":"unsupported-operation","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"}