{"record":{"id":"0fe4fd5f027b9f9c","repo":"a-b-street/abstreet","slug":"weird-body-for-at","errorCode":null,"errorMessage":"Weird body for {} at {}: {}","messagePattern":"Weird body for (.+?) at (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sim/src/mechanics/car.rs","lineNumber":144,"sourceCode":"                i += 1;\n            }\n\n            if result.len() < 2 {\n                // Vehicles spawning at a border start with their front at literally 0 distance.\n                // Usually by the time we first try to render, they've advanced at least a little.\n                // But sometimes there's a race when we try to immediately draw them.\n                if let Ok((pl, _)) = self\n                    .router\n                    .head()\n                    .get_polyline(map)\n                    .slice(Distance::ZERO, 2.0 * EPSILON_DIST)\n                {\n                    result = pl.into_points();\n                }\n            }\n            match PolyLine::new(result) {\n                Ok(pl) => pl,\n                Err(err) => panic!(\"Weird body for {} at {}: {}\", self.vehicle.id, now, err),\n            }\n        };\n\n        let body = match self.state {\n            CarState::ChangingLanes {\n                from,\n                to,\n                ref lc_time,\n                ..\n            } => {\n                let percent_time = 1.0 - lc_time.percent(now);\n                // TODO Can probably simplify this! Lifted from the parking case\n                // The car's body is already at 'to', so shift back\n                let mut diff = (to.offset as isize) - (from.offset as isize);\n                let from = map.get_l(from);\n                if from.dir == Direction::Fwd {\n                    diff *= -1;\n                }","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/sim/src/mechanics/car.rs#L126-L162","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Inspect the vehicle id and map position from the message; check the lane/road geometry at that location for degenerate points","Update or regenerate the map data for the affected area","Verify the lane-change interpolation produces at least 2 distinct points before calling PolyLine::new","Report/reproduce with the exact map and time so maintainers can fix the geometry handling"],"exampleFix":"// before\nErr(err) => panic!(\"Weird body for {} at {}: {}\", self.vehicle.id, now, err),\n// after\nErr(err) => {\n    error!(\"Weird body for {} at {}: {}; skipping draw\", self.vehicle.id, now, err);\n    return DrawCar::stub();\n}","handlingStrategy":"validation","validationCode":"let pts = pl.into_points();\nif pts.len() < 2 {\n    error!(\"car {} produced degenerate body at {}\", self.vehicle.id, now);\n    return DrawCar::stub();\n}","typeGuard":"fn is_valid_polyline(points: &[Pt]) -> bool { points.len() >= 2 }","tryCatchPattern":"// no recoverable error API; convert panic to logged fallback via match on PolyLine::new","preventionTips":["Validate map geometry (no degenerate/short lanes) at import time","Add a fallback stub draw instead of panicking in render code","Reproduce with the exact map before filing; note vehicle id and time"],"tags":["rust","panic","geometry","rendering"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}