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

  1. Repair the trip chain so each destination equals the next origin (insert the missing trip)
  2. Insert a synthetic leg between the mismatched endpoints
  3. 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

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


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)