{"record":{"id":"7ec1091007fdb6e2","repo":"a-b-street/abstreet","slug":"doesn-t-contain-both-and","errorCode":null,"errorMessage":"{} doesn't contain both {} and {}","messagePattern":"(.+?) doesn't contain both (.+?) and (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/objects/road.rs","lineNumber":617,"sourceCode":"            });\n        }\n    }\n\n    /// Returns all lanes located between l1 and l2, exclusive.\n    pub fn get_lanes_between(&self, l1: LaneID, l2: LaneID) -> Vec<LaneID> {\n        let mut results = Vec::new();\n        let mut found_start = false;\n        for l in &self.lanes {\n            if found_start {\n                if l.id == l1 || l.id == l2 {\n                    return results;\n                }\n                results.push(l.id);\n            } else if l.id == l1 || l.id == l2 {\n                found_start = true;\n            }\n        }\n        panic!(\"{} doesn't contain both {} and {}\", self.id, l1, l2);\n    }\n\n    /// A simple classification of if the directed road is stressful or not for cycling. Arterial\n    /// roads without a bike lane match this. Why arterial, instead of looking at speed limits?\n    /// Even on arterial roads with official speed limits lowered, in practice vehicles still\n    /// travel at the speed suggested by the design of the road.\n    // TODO Should elevation matter or not? Flat high-speed roads are still terrifying, but there's\n    // something about slogging up (or flying down!) a pothole-filled road inches from cars.\n    pub fn high_stress_for_bikes(&self, map: &Map, dir: Direction) -> bool {\n        let mut bike_lanes = false;\n        let mut can_use = false;\n        // Can a bike even use it, or is it a highway?\n        for l in &self.lanes {\n            if l.lane_type == LaneType::Biking && l.dir == dir {\n                bike_lanes = true;\n            }\n            if PathConstraints::Bike.can_use(l, map) {\n                can_use = true;","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/objects/road.rs#L599-L635","documentation":"get_lanes_between walks the road's ordered child lanes and collects all lanes between lanes l1 and l2 (inclusive by id match). Panics when the scan finishes without having matched both lane IDs, meaning at least one lane isn't a child of this road.","triggerScenarios":"Calling road.get_lanes_between(l1, l2) where either lane belongs to a different road, or IDs are stale relative to the current map (edits applied, lanes merged/deleted).","commonSituations":"Edit code computing the range of lanes to modify (e.g. lane-type changes between two driving lanes); using persisted lane IDs from an older map version.","solutions":["Confirm both l1 and l2 are children of self.id before calling (scan children lists).","Re-resolve the lane pair from current map state (e.g. by lane type and offset) instead of cached IDs.","Update or discard stale edits JSON that references regenerated lane IDs."],"exampleFix":"// before\nlet lanes = road.get_lanes_between(a, b);\n// after\nlet kids: Vec<_> = road.children(Direction::Fwd).iter().chain(road.children(Direction::Back).iter()).map(|(l, _)| *l).collect();\nif !kids.contains(&a) || !kids.contains(&b) { anyhow::bail!(\"lanes not on {}\", road.id); }\nlet lanes = road.get_lanes_between(a, b);","handlingStrategy":"validation","validationCode":"// verify both lanes belong to the road first\nlet kids: Vec<LaneID> = road.children(Direction::Fwd).iter().chain(road.children(Direction::Back).iter()).map(|(l, _)| *l).collect();\nif !kids.contains(&l1) || !kids.contains(&l2) { return Err(anyhow!(\"lanes not on road {}\", road.id)); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not persist lane IDs across map edits; recompute by lane type/offset","Validate edits JSON lane references against the current map on load","Keep lane-range helpers total (return Option/Result)"],"tags":["invariant","lanes","stale-ids","map-edits"],"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"}