a-b-street/abstreet · error

Couldn't find a border near start

Error message

Couldn't find a {:?} border near start {}

What it means

A transit route's entry point (first stop's lane position, or the route shape's entry) must be near a map border that vehicles of the route type can enter through. If no incoming border of the required type (Bus or Train) is within border_snap_threshold, the route's start can't be connected and create_route bails.

Solutions

  1. Increase border_snap_threshold (currently 30 meters) to catch farther borders.
  2. Check that the map's incoming borders include the route type (Bus/Train) near the entry point.
  3. Trim the GTFS route shape/stops to the portion inside the map boundary.

Example fix

// before
let border_snap_threshold = Distance::meters(30.0);
// after
let border_snap_threshold = Distance::meters(100.0);
Defensive patterns

Strategy: try-catch

Validate before calling

if !map.boundary_polygon.contains_pt(route.shape.first_pt()) {
    let near = borders.closest_pt(entry_pt, border_snap_threshold);
    if near.is_none() { /* trim route or widen threshold */ }
}

Try / catch

match create_route(...) {
    Err(e) if e.to_string().contains("border near start") => {
        warn!("route {} starts off-map", route.gtfs_id); skip();
    }
    other => other?,
}

Prevention

When it happens

Trigger: finalize_transit -> create_route where route.shape.first_pt() lies outside map.boundary_polygon (route starts off-map) and borders.closest_pt(entry_pt, 30m) returns None for the vehicle-type snapper.

Common situations: Regional GTFS routes that begin far outside the map boundary; borders snapped to the wrong type (train vs bus); map boundary excluding the route's first segment by more than 30 meters.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/768100ec530c67eb. Report an issue: GitHub.

Appendix: source

Thrown at map_model/src/make/transit.rs:179

    let start = if map.boundary_polygon.contains_pt(route.shape.first_pt()) {
        map.get_ts(stops[0]).driving_pos.lane()
    } else {
        // Find the first time the route shape hits the map boundary
        let entry_pt = *map
            .boundary_polygon
            .get_outer_ring()
            .all_intersections(&route.shape)
            .get(0)
            .ok_or_else(|| anyhow!("couldn't find where shape enters map"))?;
        // Snap that to a border
        let borders = if route.route_type == RawTransitType::Bus {
            &snapper.bus_incoming_borders
        } else {
            &snapper.train_incoming_borders
        };
        match borders.closest_pt(entry_pt, border_snap_threshold) {
            Some((l, _)) => l,
            None => bail!(
                "Couldn't find a {:?} border near start {}",
                route.route_type,
                entry_pt
            ),
        }
    };

    let end_border = if map.boundary_polygon.contains_pt(route.shape.last_pt()) {
        None
    } else {
        // Find the last time the route shape hits the map boundary
        let exit_pt = *map
            .boundary_polygon
            .get_outer_ring()
            .all_intersections(&route.shape)
            .last()
            .ok_or_else(|| anyhow!("couldn't find where shape leaves map"))?;
        // Snap that to a border

View on GitHub (pinned to 0964f29315)