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

  1. Check the endpoint's lanes and PathConstraints — ensure the border has at least one drivable lane under the constraints used.
  2. Rebuild the map if recent OSM/map edits broke driving access to the endpoint.
  3. Choose a different TripEndpoint or fall back to a walking/transit trip when driving access is impossible.
  4. 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

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


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)