{"record":{"id":"41b0fbb85c7527b0","repo":"a-b-street/abstreet","slug":"some-individtrip-wasn-t-associated-with-a-person","errorCode":null,"errorMessage":"Some IndividTrip wasn't associated with a Person?!","messagePattern":"Some IndividTrip wasn't associated with a Person\\?!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"importer/src/soundcast/trips.rs","lineNumber":287,"sourceCode":"            let destination = &pair[0].destination;\n            let origin = &pair[1].origin;\n            if destination != origin {\n                warn!(\n                    \"Skipping {:?}, with adjacent trips that warp from {:?} to {:?}\",\n                    orig_id, destination, origin\n                );\n                continue;\n            }\n        }\n\n        people.push(PersonSpec {\n            orig_id: Some(orig_id),\n            trips,\n        });\n    }\n    for maybe_t in individ_trips {\n        if maybe_t.is_some() {\n            panic!(\"Some IndividTrip wasn't associated with a Person?!\");\n        }\n    }\n\n    Scenario {\n        scenario_name: scenario_name.to_string(),\n        map_name: map.get_name().clone(),\n        people,\n        only_seed_buses: None,\n    }\n    .remove_weird_schedules(true)\n}\n","sourceCodeStart":269,"sourceCodeEnd":299,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/importer/src/soundcast/trips.rs#L269-L299","documentation":"make_scenario builds People from per-person IndividTrip lists, draining the individ_trips vec into Option slots. Afterward it asserts every Option was consumed (Some means a trip whose person ID never matched a built Person). If any remain, it panics \"Some IndividTrip wasn't associated with a Person?!\" — an internal consistency invariant of the Soundcast import.","triggerScenarios":"Running make_scenario where the trips input references a person ID absent from the parsed population — e.g. trip rows whose per-id grouping produced a person with no matching household/person record, or trips for IDs skipped earlier during filtering.","commonSituations":"Inconsistent Soundcast person/trip files (trips referencing people dropped by earlier filters like invalid households); mismatched input file versions where _trip.tsv and person files come from different model runs; parser bugs leaving trip slots unfilled.","solutions":["Check that _trip.tsv and the person/household files come from the same Soundcast model run.","Inspect which person IDs have orphan trips and either drop those trips or add the missing person during parsing.","Ensure any filtering of people earlier in make_scenario also filters their trips (keep the two lists consistent).","Relax the invariant to a warning that discards orphan trips if lossy import is acceptable."],"exampleFix":"// before\nif maybe_t.is_some() {\n    panic!(\"Some IndividTrip wasn't associated with a Person?!\");\n}\n// after\nif maybe_t.is_some() {\n    warn!(\"Discarding IndividTrip with no matching Person\");\n}","handlingStrategy":"validation","validationCode":"// Before make_scenario, confirm every trip's person id exists:\nlet orphans: Vec<_> = trips.iter().filter(|t| !person_ids.contains(&t.person_id)).collect();\nassert!(orphans.is_empty(), \"{} orphan trips\", orphans.len());","typeGuard":null,"tryCatchPattern":"// Panics uncatchably; filter trips when filtering people:\nlet individ_trips: Vec<Option<_>> = /* build */;\n// after building people, discard leftovers instead of asserting:\nlet dropped = individ_trips.iter().filter(|t| t.is_some()).count();","preventionTips":["Apply identical filters to people and trips so IDs stay consistent.","Use one Soundcast model run for all population inputs.","Log orphan person IDs during parsing for quick diagnosis."],"tags":["panic","invariant","data-import","scenario"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}