a-b-street/abstreet · error · anyhow::Error

can't start a trip from

Error message

can't start a {} trip from {}

What it means

When a trip begins from a TripEndpoint that isn't a building or sidewalk position, maybe_new must find a driving lane the vehicle can appear on: it takes some outgoing road of the endpoint intersection and pops a lane matching the constraints. If none exists, this error naming the trip mode and endpoint index is thrown — the trip cannot physically start at that location.

Solutions

  1. Verify the spawn endpoint intersection has outgoing driving lanes matching the trip's constraints in the loaded map
  2. Regenerate trip seeds against the same map version used at simulation time
  3. Change the endpoint to a nearby intersection/building with drivable access
  4. Fall back to a walking or transit trip when no driving lane exists

Example fix

// before
.and_then(|dr| dr.lanes(constraints, map).pop())
.ok_or_else(|| anyhow!("can't start a {} trip from {}", mode.ongoing_verb(), i))?;
// after
.and_then(|dr| dr.lanes(constraints, map).pop())
.with_context(|| format!("can't start a {} trip from {}; endpoint has no outgoing drivable lane", mode.ongoing_verb(), i))
.and_then(|lane| Ok(lane)); // or skip this trip and warn instead of failing the batch
let start_lane = match start_lane {
    Some(l) => l,
    None => { warn!("skipping {}: no drivable lane at {}", mode.ongoing_verb(), i); continue; }
};
Defensive patterns

Strategy: fallback

Validate before calling

// before spawning
if let TripEndpoint::Border(i) = endpoint {
    let ok = map.get_i(i).some_outgoing_road(map)
        .and_then(|dr| dr.lanes(constraints, map).pop()).is_some();
    if !ok { /* relocate endpoint or change mode */ }
}

Try / catch

match spawner.maybe_new(...) { Err(e) if e.to_string().starts_with("can't start a") => { warn!("{}; skipping trip", e); continue; }, r => r }

Prevention

When it happens

Trigger: Calling Spawner::maybe_new (e.g. via ScheduledTrips / endless events) where the TripEndpoint's intersection has no outgoing road with a drivable lane matching `constraints` — the and_then chain yields None for a VehicleAppearing TripSpec.

Common situations: Spawning car trips at border intersections with only incoming lanes; maps where drivable lanes were filtered by constraints (e.g. bus-only); trip seeds generated for a different map version than the one loaded; endpoints on pedestrian-only roads.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at sim/src/make/spawner.rs:251

                                car: use_vehicle.unwrap(),
                            }
                        } else {
                            TripSpec::UsingBike {
                                start: start_bldg,
                                goal,
                                bike: use_vehicle.unwrap(),
                            }
                        }
                    }
                    TripEndpoint::Border(i) => {
                        let start_lane = map
                            .get_i(i)
                            .some_outgoing_road(map)
                            // TODO Since we're now doing this right when the trip is starting,
                            // pick the least loaded lane or similar.
                            .and_then(|dr| dr.lanes(constraints, map).pop())
                            .ok_or_else(|| {
                                anyhow!("can't start a {} trip from {}", mode.ongoing_verb(), i)
                            })?;
                        TripSpec::VehicleAppearing {
                            start_pos: Position::new(start_lane, SPAWN_DIST),
                            goal,
                            use_vehicle: use_vehicle.unwrap(),
                            retry_if_no_room,
                        }
                    }
                    TripEndpoint::SuddenlyAppear(start_pos) => TripSpec::VehicleAppearing {
                        start_pos,
                        goal,
                        use_vehicle: use_vehicle.unwrap(),
                        retry_if_no_room,
                    },
                }
            }
            TripMode::Walk => TripSpec::JustWalking {
                start: start_sidewalk_spot(from, map)?,

View on GitHub (pinned to 0964f29315)