a-b-street/abstreet · error
Car with one-step route
Error message
Car with one-step route {:?} had unexpected result from maybe_handle_end: {:?} What it means
When a car's route is a single step, start_car_on_route expects maybe_handle_end to return either finished or GotoLaneEnd. Any other ActionAtEnd result is treated as an unreachable state and panics, guarding an internal invariant of the routing/driver logic.
Solutions
- Reproduce with the printed car router value and check what ActionAtEnd the endpoint produces
- If the endpoint is a parking spot/border, ensure the route handling covers it before assuming lane-end behavior
- Update map data or regenerate the route so one-step routes don't end at special endpoints
- Report the case to maintainers — this is an explicitly unexpected state
Example fix
// before
None | Some(ActionAtEnd::GotoLaneEnd) => {}
x => panic!("Car with one-step route {:?} had unexpected result from maybe_handle_end: {:?}", car.router, x),
// after
None | Some(ActionAtEnd::GotoLaneEnd) => {}
Some(ActionAtEnd::GotoParkingSpot { .. }) => {} // handle endpoint explicitly
x => panic!("unexpected {:?}", x), Defensive patterns
Strategy: validation
Validate before calling
if car.router.get_steps().len() == 1 {
debug_assert!(matches!(maybe_handle_end(..), None | Some(ActionAtEnd::GotoLaneEnd)));
} Type guard
fn is_lane_end_result(x: &Option<ActionAtEnd>) -> bool {
matches!(x, None | Some(ActionAtEnd::GotoLaneEnd))
} Prevention
- Cover all ActionAtEnd variants for one-step routes when editing driver logic
- Add unit tests for one-step routes ending at parking spots and borders
- Check route simplification doesn't collapse routes into unexpected endpoints
When it happens
Trigger: Calling start_car_on_lane with a car whose route has exactly one step and maybe_handle_end returns an ActionAtEnd variant other than None/GotoLaneEnd (e.g. GotoParkingSpot or KeepStraight) for a one-step route.
Common situations: Routes that end directly at a parking spot or border without intermediate steps; map edits producing one-hop routes into special endpoints; bugs in route simplification.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Bad TimeInterval ..
- Bad DistanceInterval
- Can't spawn at ; it isn't that long
- Can't start at ; it's the edge of a border already
- A trip just walking from
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/a72b19b89c56d073.
Report an issue: GitHub.
Appendix: source
Thrown at sim/src/mechanics/driving.rs:245
front: start_dist,
spot: p.spot,
time_int: TimeInterval::new(now, now + delay),
blocked_starts: lanes,
};
} else {
// Have to do this early
if car.router.last_step() {
match car.router.maybe_handle_end(
start_dist,
&car.vehicle,
ctx.parking,
ctx.map,
car.trip_and_person,
&mut self.events,
) {
None | Some(ActionAtEnd::GotoLaneEnd) => {}
x => {
panic!(
"Car with one-step route {:?} had unexpected result from \
maybe_handle_end: {:?}",
car.router, x
);
}
}
// We might've decided to go park somewhere farther, so get_end_dist no longer
// makes sense.
if car.router.last_step() && start_dist > car.router.get_end_dist() {
println!(
"WARNING: {} wants to spawn at {}, which is past their end of {} on a \
one-step path {}",
car.vehicle.id,
start_dist,
car.router.get_end_dist(),
first_lane
);
params.router = car.router;View on GitHub (pinned to 0964f29315)