a-b-street/abstreet · error · anyhow::Error
No border for
Error message
No border for {} What it means
When an external trip endpoint's GPS position is outside the map boundary, import maps it to the nearest border intersection for the trip's mode. If borders.for_mode(mode) returns an empty candidate list (no incoming borders for an origin, or no outgoing for a destination), min_by_key receives an empty iterator and this error is raised naming the mode's ongoing verb.
Solutions
- Ensure the map has border intersections for all modes used by external data (rebuild including boundary roads).
- Filter external trips to modes supported by the map's borders before import.
- Fall back to snapping the GPS point to any-mode borders or the nearest building.
- Check borders.for_mode configuration and the mode's ongoing_verb to confirm the intended mode is registered.
Example fix
// before
.ok_or_else(|| anyhow!("No border for {}", mode.ongoing_verb()))?
// after
match candidates.iter().min_by_key(|b| b.gps_pos.fast_dist(gps)) {
Some(border) => Ok(TripEndpoint::Border(border.i)),
None => Ok(TripEndpoint::Building(closest_building)), // fallback
} Defensive patterns
Strategy: validation
Validate before calling
// Check border availability for the mode before importing
let (incoming, outgoing) = borders.for_mode(mode);
if is_origin && incoming.is_empty() {
// skip or re-route this trip
} Try / catch
// Catch and skip/re-mode the trip
match import(...) {
Err(e) if e.to_string().starts_with("No border for") => skip_trip_with_reason(e),
other => other,
} Prevention
- Confirm the map has incoming and outgoing borders for every mode in the dataset
- Filter external trips by supported modes before import
- Rebuild maps including major boundary-crossing roads
- Assert non-empty border lists in map post-processing for used modes
When it happens
Trigger: Importing a trip whose origin GPS is outside the map while the map has no incoming borders for that mode (or destination outside with no outgoing borders) — e.g., a mode like biking with no registered border crossings.
Common situations: Maps with few or no border connections for a transport mode; external datasets whose trips approach from directions where no border exists; misconfigured map building that excluded major roads crossing the boundary.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Some trip has negative departure time
- No building within 100m of
- Couldn't find a border near start
- Couldn't find a border near end
- Traffic signal assignment for
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/a99a5a092f618a75.
Report an issue: GitHub.
Appendix: source
Thrown at synthpop/src/external.rs:66
let borders = MapBorders::new(map);
let lookup_pt = |endpt, is_origin, mode| match endpt {
ExternalTripEndpoint::TripEndpoint(endpt) => Ok(endpt),
ExternalTripEndpoint::Position(gps) => {
let pt = gps.to_pt(map.get_gps_bounds());
if map.get_boundary_polygon().contains_pt(pt) {
match closest.closest_pt(pt, Distance::meters(100.0)) {
Some((x, _)) => Ok(x),
None => Err(anyhow!("No building within 100m of {}", gps)),
}
} else {
let (incoming, outgoing) = borders.for_mode(mode);
let candidates = if is_origin { incoming } else { outgoing };
Ok(TripEndpoint::Border(
candidates
.iter()
.min_by_key(|border| border.gps_pos.fast_dist(gps))
.ok_or_else(|| anyhow!("No border for {}", mode.ongoing_verb()))?
.i,
))
}
}
};
let mut results = Vec::new();
for person in input {
let mut spec = PersonSpec {
orig_id: None,
trips: Vec::new(),
};
for trip in person.trips {
if trip.departure < Time::START_OF_DAY {
if skip_problems {
warn!(
"Skipping trip with negative departure time {:?}",
trip.departureView on GitHub (pinned to 0964f29315)