{"record":{"id":"6d66ff2654070cd5","repo":"a-b-street/abstreet","slug":"doesn-t-connect-to","errorCode":null,"errorMessage":"{} doesn't connect to {}","messagePattern":"(.+?) doesn't connect to (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/edits/perma.rs","lineNumber":280,"sourceCode":"                let mut translated_must_stop = BTreeMap::new();\n                for (r, stop) in must_stop {\n                    translated_must_stop.insert(map.find_r_by_osm_id(r)?, stop);\n                }\n\n                // Make sure the roads exactly match up\n                let mut ss = ControlStopSign::new(map, i);\n                if translated_must_stop.len() != ss.roads.len() {\n                    bail!(\n                        \"Stop sign has {} roads now, but {} from edits\",\n                        ss.roads.len(),\n                        translated_must_stop.len()\n                    );\n                }\n                for (r, stop) in translated_must_stop {\n                    if let Some(road) = ss.roads.get_mut(&r) {\n                        road.must_stop = stop;\n                    } else {\n                        bail!(\"{} doesn't connect to {}\", i, r);\n                    }\n                }\n\n                EditIntersectionControl::StopSign(ss)\n            }\n            PermanentEditIntersectionControl::TrafficSignal(ts) => {\n                EditIntersectionControl::TrafficSignal(ts)\n            }\n            PermanentEditIntersectionControl::Closed => EditIntersectionControl::Closed,\n        };\n\n        let mut crosswalks = BTreeMap::new();\n        for (id, turn_type) in self.crosswalks {\n            let movement = MovementID::from_permanent(id, map)?;\n            // Find all TurnIDs that map to this MovementID\n            let mut turn_ids = Vec::new();\n            for turn in &map.get_i(i).turns {\n                if turn.id.to_movement(map) == movement {","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/edits/perma.rs#L262-L298","documentation":"After rebuilding a stop sign for a permanent edit, each edited road id must exist in the new ControlStopSign's road set. If a road referenced by the edit is not adjacent to the intersection anymore, the edit cannot be applied and the library bails naming the intersection and the road id.","triggerScenarios":"with_permanent applying EditIntersectionControl::StopSign where translated_must_stop contains a RoadID not present in ss.roads — typically because the permanent edits deleted, merged, or renumbered roads touching that intersection.","commonSituations":"Applying an old edits.json to a regenerated map; layering edits on top of permanent edits that changed road topology; sharing edits between slightly different map builds.","solutions":["Remove the stale road entry from the stop-sign edit (verify the road id exists on that intersection in the current map).","Recreate the stop-sign edit on the current map version via the UI or edits tooling.","If the road id was renumbered by regeneration, remap the edit with the map's id-mapping before applying."],"exampleFix":"// before (edit references road that no longer touches the intersection)\nbail!(\"{} doesn't connect to {}\", i, r);\n// after (skip/repair stale roads before applying)\nlet ss = ControlStopSign::new(map, i);\nfor (r, stop) in translated_must_stop {\n    if ss.roads.contains_key(&r) {\n        ss.roads.get_mut(&r).unwrap().must_stop = stop;\n    }\n}","handlingStrategy":"validation","validationCode":"for (r, _) in &translated_must_stop {\n    assert!(map.get_i(i).roads.contains(r), \"road {:?} no longer touches {:?}\", r, i);\n}","typeGuard":null,"tryCatchPattern":"match with_permanent(...) {\n    Err(e) if e.to_string().contains(\"doesn't connect to\") => {\n        // drop the stale stop-sign edit and re-record it\n    }\n    other => other?,\n}","preventionTips":["Never hand-edit road ids in edits files","Re-record stop-sign edits after any map regeneration","Diff permanent edits for road deletions/merges before layering stop-sign edits"],"tags":["map-edits","stop-sign","stale-reference"],"backgroundTag":"entity-not-found","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"}