a-b-street/abstreet · error
number of lanes in is now, but in the edits
Error message
number of lanes in {} is {} now, but {} in the edits What it means
PermaEdits::into_cmd converts a persisted road edit into a command by comparing the edited lane list against the road's current lanes. If the road now has a different total number of lanes than the saved edit's lanes_ltr, the edit cannot be translated onto the current map, so into_cmd bails.
Solutions
- Regenerate the map from the OSM data matching the edits, then re-apply.
- Delete the stored perma edit for that road and redo the lane change in the app.
- Update the saved EditRoad's lanes_ltr to match the current lane count before applying.
Example fix
// before: stale persisted edit
{ "lanes_ltr": [sidewalk, driving, driving] }
// after: match the road's current 4 lanes
{ "lanes_ltr": [sidewalk, driving, driving, parking] } Defensive patterns
Strategy: validation
Validate before calling
// compare persisted edit lane count to the current road before applying
let r = map.get_r(id);
if r.lanes_ltr().len() != saved.lanes_ltr.len() {
bail!("road {} lane count changed; redo this edit", id);
} Try / catch
match edits.apply(map) {
Ok(()) => (),
Err(err) if err.to_string().contains("number of lanes") => {
error!("persistent edit stale, clearing it: {}", err);
edits.commands.clear();
}
Err(err) => return Err(err),
} Prevention
- Clear or refresh persistent edits when regenerating a map.
- After OSM lane changes, manually redo lane edits for affected roads.
- Warn users at startup when stored edits no longer match the loaded map.
When it happens
Trigger: Calling Edits::apply/into_cmd where a saved EditRoad's lanes_ltr length != the current road's lane count (num_current), typically after the basemap was regenerated from changed OSM data.
Common situations: OSM changes added or removed a lane on an edited road; loading long-lived untitled/persistent edits across map re-imports; applying persistent edits after a map version upgrade.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- number of lanes in is ( fwd, back) now, but ( , ) in the…
- lane type has changed
- speed limit has changed
- access restrictions have changed
- 's road doesn't point to dst_i at all
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/102ccd821cddf1ae.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/edits/perma.rs:121
impl PermanentEditCmd {
pub fn into_cmd(self, map: &Map) -> Result<EditCmd> {
match self {
PermanentEditCmd::ChangeRoad { r, new, old } => {
let id = map.find_r_by_osm_id(r)?;
let num_current = map.get_r(id).lanes.len();
// The basemap changed -- it'd be pretty hard to understand the original
// intent of the edit.
if num_current != old.lanes_ltr.len() {
if IGNORE_OLD_LANES {
warn!("Lanes in {r} have changed since the edits, but keeping the edits anyway");
return Ok(EditCmd::ChangeRoad {
r: id,
new,
// Note we change 'old' to match the current basemap
old: EditRoad::get_orig_from_osm(map.get_r(id), map.get_config()),
});
} else {
bail!(
"number of lanes in {} is {} now, but {} in the edits",
r,
num_current,
old.lanes_ltr.len()
);
}
}
Ok(EditCmd::ChangeRoad { r: id, new, old })
}
PermanentEditCmd::ChangeIntersection { i, new, old } => {
let id = map.find_i_by_osm_id(i)?;
Ok(EditCmd::ChangeIntersection {
i: id,
new: new
.with_permanent(id, map)
.with_context(|| format!("new ChangeIntersection of {} invalid", i))?,
old: old
.with_permanent(id, map)View on GitHub (pinned to 0964f29315)