{"record":{"id":"d2e887b8df7cb5ea","repo":"a-b-street/abstreet","slug":"unknown-dpurp","errorCode":null,"errorMessage":"Unknown dpurp {}","messagePattern":"Unknown dpurp (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"importer/src/soundcast/popdat.rs","lineNumber":250,"sourceCode":") -> (HashMap<usize, Endpoint>, BTreeMap<usize, ExtraShape>) {\n    panic!(\"Can't import_parcels for popdat.bin without the scenarios feature (GDAL dependency)\");\n}\n\n// From https://github.com/psrc/soundcast/wiki/Outputs#trip-file-_triptsv, dpurp\nfn get_purpose(code: &str) -> TripPurpose {\n    match code {\n        \"0.0\" => TripPurpose::Home,\n        \"1.0\" => TripPurpose::Work,\n        \"2.0\" => TripPurpose::School,\n        \"3.0\" => TripPurpose::Escort,\n        \"4.0\" => TripPurpose::PersonalBusiness,\n        \"5.0\" => TripPurpose::Shopping,\n        \"6.0\" => TripPurpose::Meal,\n        \"7.0\" => TripPurpose::Social,\n        \"8.0\" => TripPurpose::Recreation,\n        \"9.0\" => TripPurpose::Medical,\n        \"10.0\" => TripPurpose::ParkAndRideTransfer,\n        _ => panic!(\"Unknown dpurp {}\", code),\n    }\n}\n\n// From https://github.com/psrc/soundcast/wiki/Outputs#trip-file-_triptsv, mode\nfn get_mode(code: &str) -> TripMode {\n    match code {\n        \"1.0\" => TripMode::Walk,\n        \"2.0\" => TripMode::Bike,\n        \"3.0\" | \"4.0\" | \"5.0\" => TripMode::Drive,\n        // TODO Park-and-ride and school bus as walk-to-transit is a little weird.\n        \"6.0\" | \"7.0\" | \"8.0\" => TripMode::Transit,\n        // TODO Invalid code, what's this one mean? I only see a few examples, so just default to\n        // walking.\n        \"0.0\" => TripMode::Walk,\n        _ => panic!(\"Unknown mode {}\", code),\n    }\n}\n","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/importer/src/soundcast/popdat.rs#L232-L268","documentation":"get_purpose maps the Soundcast trip file's dpurp column (a string code like \"1.0\"..\"10.0\") to a TripPurpose enum. Any dpurp value outside the enumerated set panics with \"Unknown dpurp {code}\". The import is intentionally strict: an unmodeled purpose would silently corrupt scenario data.","triggerScenarios":"Calling import_trips on a _trip.tsv whose dpurp column contains a value not in 0.0-10.0 (e.g. empty string, \"11.0\", \"NA\", non-numeric junk).","commonSituations":"A newer Soundcast model version changing the purpose codes; corrupted or hand-edited trip files; regional model variants (different PSRC output years) using extra categories; blank cells in the TSV.","solutions":["Inspect the offending row's dpurp value in the trip file and correct or impute a known code.","Add a mapping arm for the new code (or a default like TripPurpose::Home / Err) in get_purpose if the model version legitimately introduced it.","Pre-filter/normalize the TSV (map blank/NA to \"0.0\" = not home-to-home per the wiki) before import.","Pin to the Soundcast model version the importer was written against (see psrc/soundcast wiki Outputs docs)."],"exampleFix":"// before\n_ => panic!(\"Unknown dpurp {}\", code),\n// after\nother => {\n    warn!(\"Unknown dpurp {}, defaulting to Home\", other);\n    TripPurpose::Home\n}","handlingStrategy":"validation","validationCode":"const KNOWN_DPURP: [&str; 11] = [\"0.0\",\"1.0\",\"2.0\",\"3.0\",\"4.0\",\"5.0\",\"6.0\",\"7.0\",\"8.0\",\"9.0\",\"10.0\"];\nlet bad: Vec<_> = rows.iter().filter(|r| !KNOWN_DPURP.contains(&r.dpurp.as_str())).collect();\nassert!(bad.is_empty(), \"unknown dpurp values: {:?}\", bad);","typeGuard":"fn is_known_dpurp(code: &str) -> bool {\n    matches!(code, \"0.0\"|\"1.0\"|\"2.0\"|\"3.0\"|\"4.0\"|\"5.0\"|\"6.0\"|\"7.0\"|\"8.0\"|\"9.0\"|\"10.0\")\n}","tryCatchPattern":"// Panics uncatchably; sanitize before import:\nlet dpurp = if is_known_dpurp(raw) { raw } else { \"0.0\".to_string() };","preventionTips":["Pre-validate _trip.tsv columns against the wiki's enumerated codes.","Normalize blanks/NA to \"0.0\" before importing.","Pin input data to the Soundcast model version the importer supports."],"tags":["panic","enum","data-import","soundcast"],"backgroundTag":"invalid-enum-value","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"}