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
- Verify the map has sidewalk data covering the border intersection (rebuild the map from current OSM input).
- Pick a different TripEndpoint (e.g., a nearby Building) when the target border cannot be resolved.
- Check SidewalkSpot::end_at_border logic for the intersection and whether its roads have walking infrastructure.
- 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
- Validate border walkability before constructing TripSpec::JustWalking
- Rebuild maps after OSM edits so sidewalk data stays in sync with borders
- Prefer building endpoints for walking trips in synthetic data
- Log the failing intersection ID to check its road/lane walking attributes
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
- can't end at for
- Car with one-step route
- can't figure out PathRequest from
- can't fulfill
- can't start a trip from
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)