a-b-street/abstreet · error

Some trip has negative departure time

Error message

Some trip has negative departure time {:?}

What it means

During external population import, trips are validated and any trip whose departure time is negative makes the whole import fail. A code path exists to warn and skip such trips, but when that path is not taken the import bails on the first negative departure.

Solutions

  1. Fix or regenerate the input population so all trip departures are non-negative
  2. Normalize timestamps to the simulation's time origin before import
  3. Pre-filter the dataset to drop negative-departure trips
  4. If skipping is acceptable, adjust the import code to always use the warn+continue branch

Example fix

// before
let departure = raw.ts; // may be negative
// after
let departure = raw.ts.max(Time::START_OF_DAY);
Defensive patterns

Strategy: validation

Validate before calling

if trips.iter().any(|t| t.depart < Time::START_OF_DAY) {
    return Err(anyhow!("input has negative departure times"));
}

Try / catch

match import(raw) {
    Ok(p) => p,
    Err(e) if e.to_string().contains("negative departure") => {
        eprintln!("normalizing timestamps and retrying");
        import(normalize_departures(raw))?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Importing an external population/scenario file where one or more trips have departure times before the simulation's time origin (negative Time), typically due to misaligned day offsets or malformed timestamps.

Common situations: Feed data with timestamps from a different day boundary or timezone, precomputed populations exported with unsigned-to-signed conversion bugs, joining datasets without normalizing departure times.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at synthpop/src/external.rs:88

            }
        };

        let mut results = Vec::new();
        for person in input {
            let mut spec = PersonSpec {
                orig_id: None,
                trips: Vec::new(),
            };
            for trip in person.trips {
                if trip.departure < Time::START_OF_DAY {
                    if skip_problems {
                        warn!(
                            "Skipping trip with negative departure time {:?}",
                            trip.departure
                        );
                        continue;
                    } else {
                        bail!("Some trip has negative departure time {:?}", trip.departure);
                    }
                }

                spec.trips.push(IndividTrip::new(
                    trip.departure,
                    trip.purpose,
                    match lookup_pt(trip.origin, true, trip.mode) {
                        Ok(endpt) => endpt,
                        Err(err) => {
                            if skip_problems {
                                warn!("Skipping person: {}", err);
                                continue;
                            } else {
                                return Err(err);
                            }
                        }
                    },
                    match lookup_pt(trip.destination, false, trip.mode) {

View on GitHub (pinned to 0964f29315)