{"record":{"id":"a72b19b89c56d073","repo":"a-b-street/abstreet","slug":"car-with-one-step-route-had-unexpected-result-from-maybe","errorCode":null,"errorMessage":"Car with one-step route {:?} had unexpected result from maybe_handle_end: {:?}","messagePattern":"Car with one-step route (.+?) had unexpected result from maybe_handle_end: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sim/src/mechanics/driving.rs","lineNumber":245,"sourceCode":"                    front: start_dist,\n                    spot: p.spot,\n                    time_int: TimeInterval::new(now, now + delay),\n                    blocked_starts: lanes,\n                };\n            } else {\n                // Have to do this early\n                if car.router.last_step() {\n                    match car.router.maybe_handle_end(\n                        start_dist,\n                        &car.vehicle,\n                        ctx.parking,\n                        ctx.map,\n                        car.trip_and_person,\n                        &mut self.events,\n                    ) {\n                        None | Some(ActionAtEnd::GotoLaneEnd) => {}\n                        x => {\n                            panic!(\n                                \"Car with one-step route {:?} had unexpected result from \\\n                                 maybe_handle_end: {:?}\",\n                                car.router, x\n                            );\n                        }\n                    }\n                    // We might've decided to go park somewhere farther, so get_end_dist no longer\n                    // makes sense.\n                    if car.router.last_step() && start_dist > car.router.get_end_dist() {\n                        println!(\n                            \"WARNING: {} wants to spawn at {}, which is past their end of {} on a \\\n                             one-step path {}\",\n                            car.vehicle.id,\n                            start_dist,\n                            car.router.get_end_dist(),\n                            first_lane\n                        );\n                        params.router = car.router;","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/sim/src/mechanics/driving.rs#L227-L263","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nNone | Some(ActionAtEnd::GotoLaneEnd) => {}\nx => panic!(\"Car with one-step route {:?} had unexpected result from maybe_handle_end: {:?}\", car.router, x),\n// after\nNone | Some(ActionAtEnd::GotoLaneEnd) => {}\nSome(ActionAtEnd::GotoParkingSpot { .. }) => {} // handle endpoint explicitly\nx => panic!(\"unexpected {:?}\", x),","handlingStrategy":"validation","validationCode":"if car.router.get_steps().len() == 1 {\n    debug_assert!(matches!(maybe_handle_end(..), None | Some(ActionAtEnd::GotoLaneEnd)));\n}","typeGuard":"fn is_lane_end_result(x: &Option<ActionAtEnd>) -> bool {\n    matches!(x, None | Some(ActionAtEnd::GotoLaneEnd))\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","panic","routing","simulation"],"backgroundTag":"invalid-state-transition","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}