{"record":{"id":"276f31073c0e6c1d","repo":"a-b-street/abstreet","slug":"couldn-t-find-a-border-near-end","errorCode":null,"errorMessage":"Couldn't find a {:?} border near end {}","messagePattern":"Couldn't find a (.+?) border near end (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/make/transit.rs","lineNumber":214,"sourceCode":"            .ok_or_else(|| anyhow!(\"couldn't find where shape leaves map\"))?;\n        // Snap that to a border\n        let borders = if route.route_type == RawTransitType::Bus {\n            &snapper.bus_outgoing_borders\n        } else {\n            &snapper.train_outgoing_borders\n        };\n        match borders.closest_pt(exit_pt, border_snap_threshold) {\n            Some((lane, _)) => {\n                // Edge case: the last stop is on the same road as the border. We can't lane-change\n                // suddenly, so match the lane in that case.\n                let last_stop_lane = map.get_ts(*stops.last().unwrap()).driving_pos.lane();\n                Some(if lane.road == last_stop_lane.road {\n                    last_stop_lane\n                } else {\n                    lane\n                })\n            }\n            None => bail!(\n                \"Couldn't find a {:?} border near end {}\",\n                route.route_type,\n                exit_pt\n            ),\n        }\n    };\n\n    // TODO This'll come from the RawTransitRoute eventually. For now, every 30 minutes.\n    let spawn_times: Vec<Time> = (0..48)\n        .map(|i| Time::START_OF_DAY + (i as f64) * Duration::minutes(30))\n        .collect();\n\n    let result = TransitRoute {\n        id: TransitRouteID(map.transit_routes.len()),\n        long_name: route.long_name.clone(),\n        short_name: route.short_name.clone(),\n        gtfs_id: route.gtfs_id.clone(),\n        stops,","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/make/transit.rs#L196-L232","documentation":"Symmetric to the start: when a route ends off-map, the last stop's driving position must be near an outgoing border of the route's vehicle type. If no such border is within the snap threshold, the route's exit can't be established and create_route bails.","triggerScenarios":"finalize_transit -> create_route where route.shape.last_pt() is outside map.boundary_polygon and the FindClosest lookup for outgoing Bus/Train borders around exit_pt finds nothing within border_snap_threshold (30m).","commonSituations":"Routes terminating outside the imported area; the nearest border is the wrong vehicle type; GTFS route shapes extending beyond the clipped map with the last stop inside.","solutions":["Increase border_snap_threshold so the exit point snaps to the nearest border.","Verify outgoing borders for the route's vehicle type exist near the route end; check map border generation.","Trim the route shape/stops so the route ends inside the map boundary."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if !map.boundary_polygon.contains_pt(route.shape.last_pt()) {\n    let near = borders.closest_pt(exit_pt, border_snap_threshold);\n    if near.is_none() { /* trim route or widen threshold */ }\n}","typeGuard":null,"tryCatchPattern":"match create_route(...) {\n    Err(e) if e.to_string().contains(\"border near end\") => {\n        warn!(\"route {} ends off-map\", route.gtfs_id); skip();\n    }\n    other => other?,\n}","preventionTips":["Clip route shapes at the map boundary so the last point is inside","Verify outgoing bus/train borders exist near the route's end","Increase the snap threshold for routes ending near the map edge"],"tags":["transit","gtfs","borders"],"backgroundTag":"resource-not-found","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"}