a-b-street/abstreet · error · anyhow::Error
Person ( ) warps from to during adjacent trips
Error message
Person ({:?}) warps from {:?} to {:?} during adjacent trips What it means
check_schedule verifies trip continuity: each trip's destination must match the next trip's origin. If they differ (the person would teleport, or 'warp'), this error reports both endpoints. Re-entering the map through a Border endpoint is explicitly exempted.
Solutions
- Repair the trip chain so each destination equals the next origin (insert the missing trip)
- Insert a synthetic leg between the mismatched endpoints
- Allow border-to-border transitions (already exempt) or normalize endpoints to Border when off-map
Example fix
// before let trips = raw_trips; // destination != next origin // after let trips = chain_trips(raw_trips); // inserts missing connecting legs
Defensive patterns
Strategy: validation
Validate before calling
for pair in person.trips.windows(2) {
let ok = pair[0].destination == pair[1].origin
|| (matches!(pair[0].destination, TripEndpoint::Border(_))
&& matches!(pair[1].origin, TripEndpoint::Border(_)));
if !ok { return Err(anyhow!("trip chain discontinuity")); }
} Try / catch
match person.check_schedule() {
Ok(()) => {},
Err(e) if e.to_string().contains("warps") => { person.trips = repair_chain(person.trips); }
Err(e) => return Err(e),
} Prevention
- Insert connecting legs when chaining trips from separate data sources
- Normalize off-map endpoints to Border so transitions are exempt
- Validate continuity right after import, before scenario building
When it happens
Trigger: Adjacent trips where trip[n].destination != trip[n+1].origin and the endpoints are not both Border variants, e.g. data where intermediate movement is missing.
Common situations: Trip chains that omit a leg (e.g. dropped transit trips), imported populations with endpoint mismatches from deduplication, border-crossing logic differences between datasets.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Person ( ) has no trips at all
- Person ( ) starts two trips in the wrong order: then
- Person ( ) has a trip from/to the same place
- Some trip has negative departure time
- CityName::new( , ) has a country code that isn't two letters
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/b89c965e77388d45.
Report an issue: GitHub.
Appendix: source
Thrown at synthpop/src/scenario.rs:188
for pair in self.trips.windows(2) {
if pair[0].depart >= pair[1].depart {
bail!(
"Person ({:?}) starts two trips in the wrong order: {} then {}",
self.orig_id,
pair[0].depart,
pair[1].depart
);
}
if pair[0].destination != pair[1].origin {
// Exiting one border and re-entering another is fine
if matches!(pair[0].destination, TripEndpoint::Border(_))
&& matches!(pair[1].origin, TripEndpoint::Border(_))
{
continue;
}
bail!(
"Person ({:?}) warps from {:?} to {:?} during adjacent trips",
self.orig_id,
pair[0].destination,
pair[1].origin
);
}
}
for trip in &self.trips {
if trip.origin == trip.destination {
bail!(
"Person ({:?}) has a trip from/to the same place: {:?}",
self.orig_id,
trip.origin
);
}
}
View on GitHub (pinned to 0964f29315)