a-b-street/abstreet · error
Empty path
Error message
Empty path
What it means
This panic fires during path construction when the pathfinding engine produces a Path with zero steps. validate_continuity, run as an internal sanity check by Path::new, treats an empty step list as a broken result because a valid path must always contain at least one lane or turn step. It signals an internal pathfinding bug, not a caller mistake.
Solutions
- Check whether start and end of the PathRequest are identical or effectively the same position and handle that case before calling pathfind
- Update map_model / regenerate the map so the map version matches the pathfind code, since graph edits can desynchronize the algorithm
- Report upstream with the PathRequest and map file; empty results indicate a pathfind algorithm bug
- Debug the pathfind v1 graph construction for the affected constraints to find why it returned no steps
Example fix
// before
let path = Path::new(map, steps, requirements);
// after
if steps.is_empty() {
return Ok(None); // or fall back to another route instead of panicking
}
let path = Path::new(map, steps, requirements); Defensive patterns
Strategy: validation
Validate before calling
fn path_is_nonempty(steps: &[PathStep]) -> bool { !steps.is_empty() }
if !path_is_nonempty(&steps) { return Err(anyhow!("pathfind returned no steps")); } Type guard
fn has_steps(steps: &[PathStep]) -> Option<&[PathStep]> {
if steps.is_empty() { None } else { Some(steps) }
} Prevention
- Handle the degenerate start == end request case before calling pathfind
- Keep map_model and map files version-matched
- Treat any empty pathfind result as a bug to report upstream
When it happens
Trigger: Calling Path::new (directly or via any pathfind request) when the underlying algorithm returns an empty Vec<PathStep>, e.g. after map edits change the road graph or when start and end collapse into a degenerate position.
Common situations: Hit by developers editing maps in A/B Street's editor, regenerating map models from new OSM data, or upgrading to a map version where pathfind internals changed; never from normal user API misuse.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- PathConstraints::from_lt
- Negative dist_ahead?!
- expected turn, but found
- modify_step broke total_length, it's now
- pathfind() returned path that warps
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/8602578d276263e9.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/pathfind/v1.rs:749
map.get_l(req.end.lane()).get_directed_parent(),
);
let pair = common.entry(key).or_insert_with(|| (req, 0));
pair.1 += 1;
}
if false {
info!(
"{} requests deduplicated down to {}",
prettyprint_usize(count_before),
prettyprint_usize(common.len())
);
}
common.into_values().collect()
}
}
fn validate_continuity(map: &Map, steps: &[PathStep]) {
if steps.is_empty() {
panic!("Empty path");
}
for pair in steps.windows(2) {
let from = match pair[0] {
PathStep::Lane(id) => map.get_l(id).last_pt(),
PathStep::ContraflowLane(id) => map.get_l(id).first_pt(),
PathStep::Turn(id) => map.get_t(id).geom.last_pt(),
PathStep::ContraflowTurn(id) => map.get_t(id).geom.first_pt(),
};
let to = match pair[1] {
PathStep::Lane(id) => map.get_l(id).first_pt(),
PathStep::ContraflowLane(id) => map.get_l(id).last_pt(),
PathStep::Turn(id) => map.get_t(id).geom.first_pt(),
PathStep::ContraflowTurn(id) => map.get_t(id).geom.last_pt(),
};
let len = from.dist_to(to);
if len > EPSILON_DIST {
println!("All steps in invalid path:");
for s in steps {View on GitHub (pinned to 0964f29315)