a-b-street/abstreet · warning
hit the map boundary at
Error message
hit the map boundary at {} What it means
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.
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.
Defensive patterns
Strategy: try-catch
Validate before calling
let dst_i = map.get_l(start).dst_i;
if map.get_i(dst_i).is_border() { /* start leads straight to boundary; skip this block */ } Try / catch
match Perimeter::single_block(map, start, &skip) {
Ok(p) => blocks.push(p),
Err(e) if e.to_string().starts_with("hit the map boundary") => {}, // expected, skip block
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Started on a road we shouldn't trace
- Starting on inner piece of a loop road
- Looped back on the same road, but not at a dead-end
- Infinite loop starting from
- No common roads
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/81a71896178bb502.
Report an issue: GitHub.
Appendix: source
Thrown at blockfinding/src/lib.rs:72
// We may start on a loop road on the "inner" direction
{
let start_r = map.get_parent(start);
if start_r.src_i == start_r.dst_i {
let i = map.get_i(start_r.src_i);
if !i.get_road_sides_sorted(map).contains(&start_road_side) {
bail!("Starting on inner piece of a loop road");
}
}
}
// We need to track which side of the road we're at, but also which direction we're facing
let mut current_road_side = start_road_side;
let mut current_intersection = map.get_l(start).dst_i;
loop {
let i = map.get_i(current_intersection);
if i.is_border() {
bail!("hit the map boundary at {}", i.orig_id);
}
let mut sorted_roads = i.get_road_sides_sorted(map);
sorted_roads.retain(|id| !skip.contains(&id.road));
let idx = sorted_roads
.iter()
.position(|x| *x == current_road_side)
.unwrap() as isize;
// Do we go clockwise or counter-clockwise around the intersection? Well, unless we're
// at a dead-end, we want to avoid the other side of the same road.
let mut next = *wraparound_get(&sorted_roads, idx + 1);
assert_ne!(next, current_road_side);
if next.road == current_road_side.road {
next = *wraparound_get(&sorted_roads, idx - 1);
assert_ne!(next, current_road_side);
if next.road == current_road_side.road {
if sorted_roads.len() != 2 {
bail!("Looped back on the same road, but not at a dead-end");View on GitHub (pinned to 0964f29315)