a-b-street/abstreet · error

Couldn't find a lane for

Error message

Couldn't find a lane for {:?} next to sidewalk {}

What it means

When creating a transit stop, the GTFS position was snapped to a sidewalk, but no driving (or train) lane adjacent to that sidewalk could accommodate the vehicle type. create_stop bails because the stop needs a drivable lane next to the sidewalk to place a driving_pos.

Solutions

  1. Check the GTFS stop coordinates and adjust them to lie near a road with a driving lane.
  2. Increase or adjust the sidewalk snap threshold / lane-search parameters in transit import so a valid lane is found.
  3. Skip the problematic stop (edit GTFS input) or verify the map's lanes near that stop allow the vehicle type.
Defensive patterns

Strategy: validation

Validate before calling

let ok = map.get_l(sidewalk_lane).road.get_lanes(map).iter().any(|l|
    vehicle.can_use(l, map));
if !ok { /* skip or relocate the stop before calling create_stop */ }

Try / catch

match create_stop(map, stop, vehicle) {
    Ok(id) => ..., 
    Err(e) if e.to_string().contains("Couldn't find a lane") => {
        warn!("skipping GTFS stop {:?}", stop.gtfs_id);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: finalize_transit -> create_stop where sidewalk_lane has no adjacent lane matching the vehicle's PathConstraints (e.g. a bus stop snapped to a sidewalk next to a footpath-only road, or a train stop with no adjacent rail lane).

Common situations: GTFS bus routes whose stop coordinates fall near sidewalks on pedestrian-only streets; bus stops on service roads with no driving lanes; train stops where the snapped sidewalk isn't next to rail lanes.

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/ad026026dc6b7ce1. Report an issue: GitHub.

Appendix: source

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

                road,
                idx: map.get_r(road).transit_stops.len(),
            };
            map.mut_road(road).transit_stops.insert(id);
            map.transit_stops.insert(
                id,
                TransitStop {
                    id,
                    name: stop.name.clone(),
                    gtfs_id: stop.gtfs_id.clone(),
                    driving_pos,
                    sidewalk_pos: *sidewalk_pos,
                    is_train_stop: vehicle == PathConstraints::Train,
                },
            );
            gtfs_to_stop_id.insert(stop.gtfs_id.clone(), id);
            Ok(())
        } else {
            bail!(
                "Couldn't find a lane for {:?} next to sidewalk {}",
                vehicle,
                sidewalk_lane
            );
        }
    } else {
        bail!("Stop position {} wasn't close to a sidewalk", stop.position);
    }
}

struct BorderSnapper {
    bus_incoming_borders: FindClosest<LaneID>,
    bus_outgoing_borders: FindClosest<LaneID>,
    train_incoming_borders: FindClosest<LaneID>,
    train_outgoing_borders: FindClosest<LaneID>,
}

impl BorderSnapper {

View on GitHub (pinned to 0964f29315)