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

  1. Reproduce with the printed car router value and check what ActionAtEnd the endpoint produces
  2. If the endpoint is a parking spot/border, ensure the route handling covers it before assuming lane-end behavior
  3. Update map data or regenerate the route so one-step routes don't end at special endpoints
  4. 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

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


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)