{"record":{"id":"2fcb2f1a8ea421ff","repo":"a-b-street/abstreet","slug":"access-restrictions-have-changed","errorCode":null,"errorMessage":"{:?} access restrictions have changed","messagePattern":"(.+?) access restrictions have changed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/edits/compat.rs","lineNumber":257,"sourceCode":"            };\n            if road.lanes_ltr[idx].dir == edits_dir {\n                bail!(\"{:?}'s road already points to dst_i\", obj);\n            }\n            road.lanes_ltr[idx].dir = edits_dir;\n        } else if let Some(obj) = cmd.remove(\"ChangeSpeedLimit\") {\n            let obj: ChangeSpeedLimit = serde_json::from_value(obj).unwrap();\n            let r = map.find_r_by_osm_id(obj.id)?;\n            let road = modified.entry(r).or_insert_with(|| map.get_r_edit(r));\n            if road.speed_limit != obj.old {\n                bail!(\"{:?} speed limit has changed\", obj);\n            }\n            road.speed_limit = obj.new;\n        } else if let Some(obj) = cmd.remove(\"ChangeAccessRestrictions\") {\n            let obj: ChangeAccessRestrictions = serde_json::from_value(obj).unwrap();\n            let r = map.find_r_by_osm_id(obj.id)?;\n            let road = modified.entry(r).or_insert_with(|| map.get_r_edit(r));\n            if road.access_restrictions != obj.old {\n                bail!(\"{:?} access restrictions have changed\", obj);\n            }\n            road.access_restrictions = obj.new.clone();\n        } else {\n            commands.push(orig);\n        }\n    }\n\n    for (r, new) in modified {\n        let old = map.get_r_edit(r);\n        commands\n            .push(serde_json::to_value(EditCmd::ChangeRoad { r, old, new }.to_perma(map)).unwrap());\n    }\n    value.as_object_mut().unwrap()[\"commands\"] = Value::Array(commands);\n    Ok(())\n}\n\n// a3af291b2966c89d63b719e41821705077d063d2 added a map-wide merge_zones field\nfn fix_merge_zones(value: &mut Value) {","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/edits/compat.rs#L239-L275","documentation":"When upgrading a ChangeAccessRestrictions command, the recorded old access restrictions (obj.old) are compared against the road's current access_restrictions. A mismatch means the edit's precondition is stale, so upgrade bails instead of applying the change on the wrong baseline.","triggerScenarios":"Loading an edit file whose ChangeAccessRestrictions.old differs from road.access_restrictions in the current map — after basemap regeneration, OSM updates, or prior edits changed restrictions.","commonSituations":"Replaying old edits onto a regenerated map; applying the same edit file twice; sharing edit files between different map versions.","solutions":["Update the command's `old` field in the edit JSON to the road's current access restrictions.","Remove the stale command and re-apply the restriction change in the app.","Regenerate the map to match the edit's recorded old restrictions."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// confirm recorded old access restrictions match the current road\nlet r = map.find_r_by_osm_id(cmd.id)?;\nif map.get_r_edit(r).access_restrictions != cmd.old { /* update or drop cmd */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Recreate access-restriction edits after each map regeneration.","Avoid stacking edits from different basemap versions.","Diff road access restrictions between map builds before loading old edits."],"tags":["edits","compatibility","state-mismatch"],"backgroundTag":"schema-validation-failed","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"}