{"record":{"id":"d4b96fdf96c00d95","repo":"a-b-street/abstreet","slug":"empty-path-between-stops","errorCode":null,"errorMessage":"Empty path between stops: {}","messagePattern":"Empty path between stops: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/objects/transit.rs","lineNumber":123,"sourceCode":"    }\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\n                );\n            }\n        }\n\n        Ok(paths)\n    }\n\n    pub fn plural_noun(&self) -> &'static str {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/objects/transit.rs#L105-L141","documentation":"After pathfinding between consecutive transit stops, all_paths checks each path for emptiness; an empty path means pathfind returned successfully but produced no steps, which cannot represent a drivable leg between stops. The library bails with the PathRequest echoed so the developer can locate the failing stop pair.","triggerScenarios":"create_route / create_empty_route on a TransitRoute where map.pathfind(req) returns Ok but the path contains zero steps for some stop pair (map_model/src/objects/transit.rs:123) — typically when start and end positions effectively coincide or are unreachable but pathfind doesn't reject them.","commonSituations":"Degenerate stop placement (both stops at the same spot), a road isolated by map edits, or a path request whose start and end snap to the same lane position after map changes.","solutions":["Inspect the PathRequest in the message and check whether its start/end snap to the same position; adjust stop placement.","Verify the roads between the stops are connected and drivable in the current map.","Remove or relocate the degenerate stop in the route definition.","Rebuild/re-import the map if its connectivity was changed after routes were defined."],"exampleFix":"// before\nlet stops = vec![stop_a, stop_a.clone()]; // same position twice\n// after\nlet stops = vec![stop_a, stop_b_distinct];","handlingStrategy":"validation","validationCode":"for pair in stops.windows(2) {\n    if pair[0] == pair[1] { return Err(\"duplicate/degenerate stop\".into()); }\n}\n// also check map connectivity between stop roads via map.pathfind on the request","typeGuard":null,"tryCatchPattern":"match route.all_paths(&map) {\n    Err(e) if e.to_string().starts_with(\"Empty path\") => {\n        let req = parse_req_from(&e);\n        // relocate or drop the degenerate stop, then rebuild\n    }\n    other => other?,\n}","preventionTips":["Reject duplicate or coincident stops when defining routes.","After map edits, re-verify connectivity between all consecutive stops.","Rebuild transit routes whenever the map version changes."],"tags":["transit","routing","pathfinding","empty-path"],"backgroundTag":"empty-result-set","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"}