{"record":{"id":"a99a5a092f618a75","repo":"a-b-street/abstreet","slug":"no-border-for","errorCode":null,"errorMessage":"No border for {}","messagePattern":"No border for (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"synthpop/src/external.rs","lineNumber":66,"sourceCode":"        let borders = MapBorders::new(map);\n\n        let lookup_pt = |endpt, is_origin, mode| match endpt {\n            ExternalTripEndpoint::TripEndpoint(endpt) => Ok(endpt),\n            ExternalTripEndpoint::Position(gps) => {\n                let pt = gps.to_pt(map.get_gps_bounds());\n                if map.get_boundary_polygon().contains_pt(pt) {\n                    match closest.closest_pt(pt, Distance::meters(100.0)) {\n                        Some((x, _)) => Ok(x),\n                        None => Err(anyhow!(\"No building within 100m of {}\", gps)),\n                    }\n                } else {\n                    let (incoming, outgoing) = borders.for_mode(mode);\n                    let candidates = if is_origin { incoming } else { outgoing };\n                    Ok(TripEndpoint::Border(\n                        candidates\n                            .iter()\n                            .min_by_key(|border| border.gps_pos.fast_dist(gps))\n                            .ok_or_else(|| anyhow!(\"No border for {}\", mode.ongoing_verb()))?\n                            .i,\n                    ))\n                }\n            }\n        };\n\n        let mut results = Vec::new();\n        for person in input {\n            let mut spec = PersonSpec {\n                orig_id: None,\n                trips: Vec::new(),\n            };\n            for trip in person.trips {\n                if trip.departure < Time::START_OF_DAY {\n                    if skip_problems {\n                        warn!(\n                            \"Skipping trip with negative departure time {:?}\",\n                            trip.departure","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/synthpop/src/external.rs#L48-L84","documentation":"When an external trip endpoint's GPS position is outside the map boundary, import maps it to the nearest border intersection for the trip's mode. If borders.for_mode(mode) returns an empty candidate list (no incoming borders for an origin, or no outgoing for a destination), min_by_key receives an empty iterator and this error is raised naming the mode's ongoing verb.","triggerScenarios":"Importing a trip whose origin GPS is outside the map while the map has no incoming borders for that mode (or destination outside with no outgoing borders) — e.g., a mode like biking with no registered border crossings.","commonSituations":"Maps with few or no border connections for a transport mode; external datasets whose trips approach from directions where no border exists; misconfigured map building that excluded major roads crossing the boundary.","solutions":["Ensure the map has border intersections for all modes used by external data (rebuild including boundary roads).","Filter external trips to modes supported by the map's borders before import.","Fall back to snapping the GPS point to any-mode borders or the nearest building.","Check borders.for_mode configuration and the mode's ongoing_verb to confirm the intended mode is registered."],"exampleFix":"// before\n.ok_or_else(|| anyhow!(\"No border for {}\", mode.ongoing_verb()))?\n// after\nmatch candidates.iter().min_by_key(|b| b.gps_pos.fast_dist(gps)) {\n    Some(border) => Ok(TripEndpoint::Border(border.i)),\n    None => Ok(TripEndpoint::Building(closest_building)), // fallback\n}","handlingStrategy":"validation","validationCode":"// Check border availability for the mode before importing\nlet (incoming, outgoing) = borders.for_mode(mode);\nif is_origin && incoming.is_empty() {\n    // skip or re-route this trip\n}","typeGuard":null,"tryCatchPattern":"// Catch and skip/re-mode the trip\nmatch import(...) {\n    Err(e) if e.to_string().starts_with(\"No border for\") => skip_trip_with_reason(e),\n    other => other,\n}","preventionTips":["Confirm the map has incoming and outgoing borders for every mode in the dataset","Filter external trips by supported modes before import","Rebuild maps including major boundary-crossing roads","Assert non-empty border lists in map post-processing for used modes"],"tags":["import","synthpop","borders","map-data"],"backgroundTag":"empty-result-set","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"}