a-b-street/abstreet · error
's road already points to dst_i
Error message
{:?}'s road already points to dst_i What it means
When upgrading a ReverseLane command, if the target road's lane already points in the direction of dst_i (the change would be a no-op), the upgrade rejects the command because re-applying it is meaningless and likely indicates the edit was already applied.
Solutions
- Drop the redundant ReverseLane command from the edit JSON — the desired state already holds.
- Regenerate the map to reset the lane direction, then re-apply the edit.
- If intentional, invert the command or remove it and re-create the edit.
Defensive patterns
Strategy: validation
Validate before calling
// skip ReverseLane if the lane already points toward dst_i
let dir = if dst_i == map.get_r(r).dst_i { Direction::Fwd } else { Direction::Back };
if map.get_r_edit(r).lanes_ltr[idx].dir == dir { /* drop redundant cmd */ } Prevention
- Don't apply the same edit file twice; track applied edit filenames.
- Remove redundant commands from edit files before sharing them.
- Regenerate edits after changes become part of the basemap.
When it happens
Trigger: Loading an edit file whose ReverseLane command targets a lane whose current dir already equals the edits_dir computed from dst_i — typically after the edit was already applied or the basemap changed to match.
Common situations: Double-applying an edit file; loading an edit after the change became part of the basemap regeneration.
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
- lane type has changed
- 's road doesn't point to dst_i at all
- speed limit has changed
- access restrictions have changed
- None of the edits apply to this map
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/444536f10bc775b9.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/edits/compat.rs:241
let road = modified.entry(r).or_insert_with(|| map.get_r_edit(r));
if road.lanes_ltr[idx].lt != obj.orig_lt {
bail!("{:?} lane type has changed", obj);
}
road.lanes_ltr[idx].lt = obj.lt;
} else if let Some(obj) = cmd.remove("ReverseLane") {
let obj: ReverseLane = serde_json::from_value(obj).unwrap();
let (r, idx) = obj.l.lookup(map)?;
let dst_i = map.find_i_by_osm_id(obj.dst_i)?;
let road = modified.entry(r).or_insert_with(|| map.get_r_edit(r));
let edits_dir = if dst_i == map.get_r(r).dst_i {
Direction::Fwd
} else if dst_i == map.get_r(r).src_i {
Direction::Back
} else {
bail!("{:?}'s road doesn't point to dst_i at all", obj);
};
if road.lanes_ltr[idx].dir == edits_dir {
bail!("{:?}'s road already points to dst_i", obj);
}
road.lanes_ltr[idx].dir = edits_dir;
} else if let Some(obj) = cmd.remove("ChangeSpeedLimit") {
let obj: ChangeSpeedLimit = serde_json::from_value(obj).unwrap();
let r = map.find_r_by_osm_id(obj.id)?;
let road = modified.entry(r).or_insert_with(|| map.get_r_edit(r));
if road.speed_limit != obj.old {
bail!("{:?} speed limit has changed", obj);
}
road.speed_limit = obj.new;
} else if let Some(obj) = cmd.remove("ChangeAccessRestrictions") {
let obj: ChangeAccessRestrictions = serde_json::from_value(obj).unwrap();
let r = map.find_r_by_osm_id(obj.id)?;
let road = modified.entry(r).or_insert_with(|| map.get_r_edit(r));
if road.access_restrictions != obj.old {
bail!("{:?} access restrictions have changed", obj);
}
road.access_restrictions = obj.new.clone();View on GitHub (pinned to 0964f29315)