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

Person ( ) has a trip from/to the same place

Error message

Person ({:?}) has a trip from/to the same place: {:?}

What it means

check_schedule rejects any individual trip whose origin and destination are the same endpoint, since a trip from a place to itself is meaningless in the model. The error names the person and the offending origin.

Solutions

  1. Drop trips with identical origin and destination before check_schedule
  2. Split them into meaningful legs or convert the person to stay-at-home with no trips (then filter per error 175)
  3. Fix the upstream generator/importer that emits degenerate trips

Example fix

// before
trips.retain(|t| true);
// after
trips.retain(|t| t.origin != t.destination);
Defensive patterns

Strategy: validation

Validate before calling

person.trips.retain(|t| t.origin != t.destination);

Try / catch

match person.check_schedule() {
    Ok(()) => {},
    Err(e) if e.to_string().contains("same place") => {
        person.trips.retain(|t| t.origin != t.destination);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A trip in the PersonSpec has origin == destination, often produced when an activity generator emits a return-to-same-place leg or import deduplicates endpoints incorrectly.

Common situations: Round-trip data recorded as a single degenerate trip, activity models emitting zero-length trips for same-building activities (related to the home==work TODO), noisy GPS-derived trips.

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/fda233d853abccbe. Report an issue: GitHub.

Appendix: source

Thrown at synthpop/src/scenario.rs:199

            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
                );
            }
        }

        Ok(())
    }
}

View on GitHub (pinned to 0964f29315)