a-b-street/abstreet · error

Weird body for at

Error message

Weird body for {} at {}: {}

What it means

This panic fires when a vehicle's polygon body points cannot be assembled into a valid PolyLine while drawing a car. PolyLine::new rejects degenerate geometry (fewer than 2 points or zero-length segments), which usually indicates corrupted or degenerate map geometry at the car's current position.

Solutions

  1. Inspect the vehicle id and map position from the message; check the lane/road geometry at that location for degenerate points
  2. Update or regenerate the map data for the affected area
  3. Verify the lane-change interpolation produces at least 2 distinct points before calling PolyLine::new
  4. Report/reproduce with the exact map and time so maintainers can fix the geometry handling

Example fix

// before
Err(err) => panic!("Weird body for {} at {}: {}", self.vehicle.id, now, err),
// after
Err(err) => {
    error!("Weird body for {} at {}: {}; skipping draw", self.vehicle.id, now, err);
    return DrawCar::stub();
}
Defensive patterns

Strategy: validation

Validate before calling

let pts = pl.into_points();
if pts.len() < 2 {
    error!("car {} produced degenerate body at {}", self.vehicle.id, now);
    return DrawCar::stub();
}

Type guard

fn is_valid_polyline(points: &[Pt]) -> bool { points.len() >= 2 }

Try / catch

// no recoverable error API; convert panic to logged fallback via match on PolyLine::new

Prevention

When it happens

Trigger: Rendering a car whose body, after transformation (e.g. into_points during lane-change interpolation), yields points that PolyLine::new rejects — typically an empty or single-point result at a specific simulation time `now`.

Common situations: Map data with degenerate lanes or very short/overlapping lanes; cars mid-lane-change at boundaries where interpolated points collapse; custom/imported maps with bad geometry.

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


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/0fe4fd5f027b9f9c. Report an issue: GitHub.

Appendix: source

Thrown at sim/src/mechanics/car.rs:144

                i += 1;
            }

            if result.len() < 2 {
                // Vehicles spawning at a border start with their front at literally 0 distance.
                // Usually by the time we first try to render, they've advanced at least a little.
                // But sometimes there's a race when we try to immediately draw them.
                if let Ok((pl, _)) = self
                    .router
                    .head()
                    .get_polyline(map)
                    .slice(Distance::ZERO, 2.0 * EPSILON_DIST)
                {
                    result = pl.into_points();
                }
            }
            match PolyLine::new(result) {
                Ok(pl) => pl,
                Err(err) => panic!("Weird body for {} at {}: {}", self.vehicle.id, now, err),
            }
        };

        let body = match self.state {
            CarState::ChangingLanes {
                from,
                to,
                ref lc_time,
                ..
            } => {
                let percent_time = 1.0 - lc_time.percent(now);
                // TODO Can probably simplify this! Lifted from the parking case
                // The car's body is already at 'to', so shift back
                let mut diff = (to.offset as isize) - (from.offset as isize);
                let from = map.get_l(from);
                if from.dir == Direction::Fwd {
                    diff *= -1;
                }

View on GitHub (pinned to 0964f29315)