a-b-street/abstreet · error · anyhow::Error
Person ( ) starts two trips in the wrong order: then
Error message
Person ({:?}) starts two trips in the wrong order: {} then {} What it means
check_schedule requires trips to be sorted by departure time. If any adjacent pair has pair[0].depart >= pair[1].depart, the schedule is invalid and this error names the person and both departure times.
Solutions
- Sort the trips by departure time before calling check_schedule
- Break ties by nudging one departure slightly later or merging trips
- Validate/sort in the import pipeline before constructing the scenario
Example fix
// before
let spec = PersonSpec { trips: trips, .. };
// after
trips.sort_by_key(|t| t.depart);
let spec = PersonSpec { trips, .. }; Defensive patterns
Strategy: validation
Validate before calling
person.trips.sort_by_key(|t| t.depart);
Try / catch
match person.check_schedule() {
Ok(()) => {},
Err(e) if e.to_string().contains("wrong order") => {
person.trips.sort_by_key(|t| t.depart);
}
Err(e) => return Err(e),
} Prevention
- Always sort trips by departure time after import or merge
- Break equal timestamps deterministically (offset by 1 second)
- Call check_schedule immediately after building each PersonSpec
When it happens
Trigger: Building a PersonSpec whose trips are not strictly increasing in departure time, including trips that depart at exactly the same time.
Common situations: External population files with unsorted trips, merging multiple data sources without re-sorting, floating/second-granularity collisions producing equal timestamps.
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 ( ) warps from to during adjacent trips
- 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/ed98f791169bcea3.
Report an issue: GitHub.
Appendix: source
Thrown at synthpop/src/scenario.rs:173
return x.to_string();
}
}
}
// Dynamically generated -- arguably this is an absence of a default scenario
"home_to_work".to_string()
}
}
impl PersonSpec {
/// Verify that a person's trips make sense
pub fn check_schedule(&self) -> Result<()> {
if self.trips.is_empty() {
bail!("Person ({:?}) has no trips at all", self.orig_id);
}
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,View on GitHub (pinned to 0964f29315)