a-b-street/abstreet · error · anyhow::Error

can't end walking at

Error message

can't end walking at {}

What it means

This error is thrown by end_sidewalk_spot when converting a TripEndpoint::Border into a SidewalkSpot for the walking leg of a trip. SidewalkSpot::end_at_border returns None when the map cannot resolve the border intersection to a walkable sidewalk spot, so the spawner raises this anyhow error. It means trip scheduling data is inconsistent with the map's pedestrian network at that border.

Solutions

  1. Verify the map has sidewalk data covering the border intersection (rebuild the map from current OSM input).
  2. Pick a different TripEndpoint (e.g., a nearby Building) when the target border cannot be resolved.
  3. Check SidewalkSpot::end_at_border logic for the intersection and whether its roads have walking infrastructure.
  4. Fall back to TripEndpoint::SuddenlyAppear only in synthetic/testing contexts, never production.

Example fix

// before
TripEndpoint::Border(i) => {
    SidewalkSpot::end_at_border(i, map)
        .ok_or_else(|| anyhow!("can't end walking at {}", i))
}
// after (caller guards with a fallback endpoint)
let endpt = if SidewalkSpot::end_at_border(i, map).is_some() {
    endpt
} else {
    TripEndpoint::Building(map.find_nearest_building(pt))
};
Defensive patterns

Strategy: validation

Validate before calling

// Validate the walking endpoint before scheduling
fn walking_ok(endpt: &TripEndpoint, map: &Map) -> bool {
    match endpt {
        TripEndpoint::Building(_) => true,
        TripEndpoint::Border(i) => SidewalkSpot::end_at_border(*i, map).is_some(),
        TripEndpoint::SuddenlyAppear(_) => false,
    }
}

Type guard

fn is_walkable_border(endpt: &TripEndpoint, map: &Map) -> Option<IntersectionID> {
    match endpt {
        TripEndpoint::Border(i) if SidewalkSpot::end_at_border(*i, map).is_some() => Some(*i),
        _ => None,
    }
}

Prevention

When it happens

Trigger: A trip is created via TripSpec::JustWalking or maybe_new with TripEndpoint::Border(i), and SidewalkSpot::end_at_border(i, map) returns None — i.e., the border intersection has no sidewalk/road mapping usable as a walking destination.

Common situations: Custom maps or map edits that removed or never generated sidewalks near a border; programmatically generated trips (e.g., synthetic population imports) targeting borders on a map where walking routes to that border are unavailable.

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

Appendix: source

Thrown at sim/src/make/spawner.rs:308

            }
        })
    }
}

fn start_sidewalk_spot(endpt: TripEndpoint, map: &Map) -> Result<SidewalkSpot> {
    match endpt {
        TripEndpoint::Building(b) => Ok(SidewalkSpot::building(b, map)),
        TripEndpoint::Border(i) => SidewalkSpot::start_at_border(i, map)
            .ok_or_else(|| anyhow!("can't start walking from {}", i)),
        TripEndpoint::SuddenlyAppear(pos) => Ok(SidewalkSpot::suddenly_appear(pos, map)),
    }
}

fn end_sidewalk_spot(endpt: TripEndpoint, map: &Map) -> Result<SidewalkSpot> {
    match endpt {
        TripEndpoint::Building(b) => Ok(SidewalkSpot::building(b, map)),
        TripEndpoint::Border(i) => {
            SidewalkSpot::end_at_border(i, map).ok_or_else(|| anyhow!("can't end walking at {}", i))
        }
        TripEndpoint::SuddenlyAppear(_) => unreachable!(),
    }
}

fn driving_goal(
    endpt: TripEndpoint,
    constraints: PathConstraints,
    map: &Map,
) -> Result<DrivingGoal> {
    match endpt {
        TripEndpoint::Building(b) => Ok(DrivingGoal::ParkNear(b)),
        // TODO Duplicates some logic from TripEndpoint::pos
        TripEndpoint::Border(i) => map
            .get_i(i)
            .some_incoming_road(map)
            .and_then(|dr| {
                let lanes = dr.lanes(constraints, map);

View on GitHub (pinned to 0964f29315)