a-b-street/abstreet · error · anyhow::Error
can't end at for
Error message
can't end at {} for {:?} What it means
driving_goal builds the destination for the driving leg of a trip. For a TripEndpoint::Border, it resolves the border's destination intersection and the first drivable lane; for buildings it pathfinds via PathConstraints-based access. When no suitable driving lane/goal can be produced under the vehicle's PathConstraints, this anyhow error is raised with the endpoint and constraints.
Solutions
- Check the endpoint's lanes and PathConstraints — ensure the border has at least one drivable lane under the constraints used.
- Rebuild the map if recent OSM/map edits broke driving access to the endpoint.
- Choose a different TripEndpoint or fall back to a walking/transit trip when driving access is impossible.
- Inspect the constraints value in the message and align it with the vehicle type being spawned.
Example fix
// before
.ok_or_else(|| anyhow!("can't end at {} for {:?}", i, constraints))
// after: caller validates access before scheduling
if map.get_i(i).get_outgoing_lanes(PathConstraints::Car).is_empty() {
// fall back to a different endpoint or mode
} Defensive patterns
Strategy: validation
Validate before calling
// Check driving access for a border endpoint before scheduling
fn drivable(endpt: &TripEndpoint, constraints: PathConstraints, map: &Map) -> bool {
match endpt {
TripEndpoint::Border(i) => !map.get_i(*i).get_outgoing_lanes(constraints).is_empty(),
TripEndpoint::Building(b) => map.get_b(*b).get_driving_connection(|l| l != PathConstraints::Bike).is_some() || map.get_b(*b).get_driving_connection(|l| true).is_some(),
_ => true,
}
} Try / catch
// Catch and fall back to a different mode/endpoint
match maybe_new(...) {
Ok(t) => t,
Err(e) if e.to_string().contains("can't end at") => {
// retry with a fallback endpoint or walking trip
fallback_trip(endpt)
}
Err(e) => return Err(e),
} Prevention
- Match PathConstraints to the endpoint's actual lane types
- Verify borders have car-accessible lanes when generating border-targeted trips
- Test trip generation over all borders of a map before bulk runs
- Include the constraints value in logs to quickly spot constraint/endpoint mismatches
When it happens
Trigger: maybe_new schedules a driving trip whose TripEndpoint::Border(i) has no drivable lanes under the given PathConstraints, or a building endpoint yields no parking/driveway path under those constraints, so the option chain returns None.
Common situations: Border with only bus/bike lanes and no car-accessible lane; cars-only or bikes-only constraint sets applied to endpoints that don't support that mode; map edits that removed road access to a building or border.
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 walking at
- 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/4d3d01a4e30b7027.
Report an issue: GitHub.
Appendix: source
Thrown at sim/src/make/spawner.rs:334
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);
if lanes.is_empty() {
None
} else {
// TODO ideally could use any
Some(DrivingGoal::Border(dr.dst_i(map), lanes[0]))
}
})
.ok_or_else(|| anyhow!("can't end at {} for {:?}", i, constraints)),
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
}
}
View on GitHub (pinned to 0964f29315)