{"record":{"id":"cb740297ec46ce2b","repo":"a-b-street/abstreet","slug":"two-consecutive-stops-are-on-the-same-road-but-they-travel","errorCode":null,"errorMessage":"Two consecutive stops are on the same road, but they travel backwards: {}","messagePattern":"Two consecutive stops are on the same road, but they travel backwards: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/objects/transit.rs","lineNumber":115,"sourceCode":"            // Drive to the end of the lane with the last stop\n            steps.push(PathRequest::vehicle(\n                last_stop_pos,\n                Position::end(last_stop_pos.lane(), map),\n                self.route_type,\n            ));\n        }\n        steps\n    }\n\n    /// Entry i is the path to drive to stop i. The very last entry is to drive from the last step\n    /// to the place where the vehicle vanishes.\n    pub fn all_paths(&self, map: &Map) -> Result<Vec<Path>> {\n        let mut paths = Vec::new();\n        for req in self.all_path_requests(map) {\n            if req.start.lane().road == req.end.lane().road\n                && req.start.dist_along() > req.end.dist_along()\n            {\n                bail!(\n                    \"Two consecutive stops are on the same road, but they travel backwards: {}\",\n                    req\n                );\n            }\n\n            let path = map.pathfind(req)?;\n            if path.is_empty() {\n                bail!(\"Empty path between stops: {}\", path.get_req());\n            }\n            paths.push(path);\n        }\n\n        for pair in paths.windows(2) {\n            if pair[0].get_req().end != pair[1].get_req().start {\n                bail!(\n                    \"Transit route will warp from {} to {}\",\n                    pair[0].get_req().end,\n                    pair[1].get_req().start","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/objects/transit.rs#L97-L133","documentation":"Transit route construction walks consecutive stop pairs and builds a path request for each. If two consecutive stops lie on the same road but the requested trip goes backwards along it (start.dist_along() > end.dist_along()), no forward path exists, so all_paths bails. The library refuses to synthesize U-turn or reversed travel for transit vehicles.","triggerScenarios":"Creating a transit route (create_route / create_empty_route) where stop N and stop N+1 are on the same road but the vehicle must travel in reverse direction of the road's lane ordering, i.e. req.start.dist_along() > req.end.dist_along() (map_model/src/objects/transit.rs:115).","commonSituations":"Transit data (GTFS-like imports) where stops are placed by position rather than driving direction, or a route loops back along the same road; also bidirectional stops auto-assigned to the wrong side of the street.","solutions":["Reorder or remove the offending stop pair in the transit route so travel proceeds forward along the road.","Move one of the stops to the opposite side / correctly directed road in the map editor.","Split the route into two routes at the turnaround point, inserting a loop via different roads.","Rebuild the map so the road is split at the stop, giving each stop its own correctly directed road."],"exampleFix":"// before: stops A (dist 900) then B (dist 100) on same road\nlet route = TransitRoute::create_route(&map, vec![stop_a, stop_b])?;\n// after: place stop B on the opposite-direction road or reorder\nlet route = TransitRoute::create_route(&map, vec![stop_b_opposite_dir, stop_a])?;","handlingStrategy":"validation","validationCode":"for pair in stops.windows(2) {\n    if pair[0].lane().road == pair[1].lane().road\n        && pair[0].dist_along() > pair[1].dist_along() {\n        return Err(format!(\"backwards pair on road {}\", pair[0].lane().road));\n    }\n}","typeGuard":null,"tryCatchPattern":"match TransitRoute::create_route(&map, stops) {\n    Err(e) if e.to_string().starts_with(\"Two consecutive stops\") => {\n        // fix stop ordering/placement and retry\n    }\n    other => other?,\n}","preventionTips":["Assign transit stops to lanes matching the travel direction of the route.","Validate route stop ordering against road geometry before route creation.","Split looping routes at turnarounds instead of reversing along the same road."],"tags":["transit","routing","map-model","stops"],"backgroundTag":"invalid-argument-value","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"}