a-b-street/abstreet · error
Can't spawn at ; it isn't that long
Error message
Can't spawn at {}; it isn't that long What it means
When turning spawn specifications into trip plans, a TripSpec starting at a Position whose dist_along exceeds or equals the lane's total length cannot be placed on that lane. The library panics because there is no valid geometry for a car beyond the end of its lane.
Solutions
- Clamp dist_along to be strictly less than the lane length before spawning
- Pick a different lane or shift the spawn back from the lane end
- Regenerate the scenario against the current (possibly edited) map geometry
Example fix
// before let pos = Position::new(lane, length); // after let pos = Position::new(lane, length - Distance::meters(0.1)).min_lane_end();
Defensive patterns
Strategy: validation
Validate before calling
let lane_len = map.get_l(start_pos.lane()).length();
if start_pos.dist_along() >= lane_len {
start_pos = start_pos.min_lane_end(); // clamp before building TripSpec
} Type guard
fn spawnable(pos: &Position, map: &Map) -> bool {
pos.dist_along() < map.get_l(pos.lane()).length()
} Try / catch
let plan = std::panic::catch_unwind(|| spec.into_plan(&map, &mut rng));
Prevention
- Clamp dist_along to length - epsilon when sampling uniformly along lanes
- Regenerate scenarios after map edits change lane lengths
When it happens
Trigger: into_plan() called with a TripSpec::Vehicle whose start_pos.dist_along() >= map.get_l(start_pos.lane()).length(), e.g. a spawn position at or past the lane end.
Common situations: Scenario generators computing dist_along from percentages without clamping (1.0 * length); floating-point rounding pushing dist_along just past the lane length; reusing positions from a differently-edited map where lanes were shortened by edits.
Related errors
- Bad TimeInterval ..
- Bad DistanceInterval
- Can't start at ; it's the edge of a border already
- A trip just walking from
- trying to make a crossing_state from to at . Something's…
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/b7900b749e9da7eb.
Report an issue: GitHub.
Appendix: source
Thrown at sim/src/make/spawner.rs:72
route: TransitRouteID,
stop1: TransitStopID,
maybe_stop2: Option<TransitStopID>,
},
}
impl TripSpec {
pub fn into_plan(self, map: &Map) -> (TripSpec, Vec<TripLeg>) {
// TODO We'll want to repeat this validation when we spawn stuff later for a second leg...
let mut legs = Vec::new();
match &self {
TripSpec::VehicleAppearing {
start_pos,
goal,
use_vehicle,
..
} => {
if start_pos.dist_along() >= map.get_l(start_pos.lane()).length() {
panic!("Can't spawn at {}; it isn't that long", start_pos);
}
if let DrivingGoal::Border(_, end_lane) = goal {
if start_pos.lane() == *end_lane
&& start_pos.dist_along() == map.get_l(*end_lane).length()
{
panic!(
"Can't start at {}; it's the edge of a border already",
start_pos
);
}
}
let constraints = if use_vehicle.vehicle_type == VehicleType::Bike {
PathConstraints::Bike
} else {
PathConstraints::Car
};
View on GitHub (pinned to 0964f29315)