{"record":{"id":"4d25868be5f6fbb4","repo":"a-b-street/abstreet","slug":"no-valid-stops","errorCode":null,"errorMessage":"No valid stops","messagePattern":"No valid stops","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/make/transit.rs","lineNumber":157,"sourceCode":"        }\n        snapper\n    }\n}\n\nfn create_route(\n    route: &RawTransitRoute,\n    map: &mut Map,\n    gtfs_to_stop_id: &HashMap<String, TransitStopID>,\n    snapper: &BorderSnapper,\n) -> Result<()> {\n    // TODO At least warn about stops that failed to snap\n    let stops: Vec<TransitStopID> = route\n        .stops\n        .iter()\n        .filter_map(|gtfs_id| gtfs_to_stop_id.get(gtfs_id).cloned())\n        .collect();\n    if stops.is_empty() {\n        bail!(\"No valid stops\");\n    }\n    let border_snap_threshold = Distance::meters(30.0);\n\n    let start = if map.boundary_polygon.contains_pt(route.shape.first_pt()) {\n        map.get_ts(stops[0]).driving_pos.lane()\n    } else {\n        // Find the first time the route shape hits the map boundary\n        let entry_pt = *map\n            .boundary_polygon\n            .get_outer_ring()\n            .all_intersections(&route.shape)\n            .get(0)\n            .ok_or_else(|| anyhow!(\"couldn't find where shape enters map\"))?;\n        // Snap that to a border\n        let borders = if route.route_type == RawTransitType::Bus {\n            &snapper.bus_incoming_borders\n        } else {\n            &snapper.train_incoming_borders","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/make/transit.rs#L139-L175","documentation":"While creating a transit route, each GTFS stop id must have been successfully created earlier (gtfs_to_stop_id). If none of the route's stops resolved to a TransitStopID, the route has no valid stops and cannot be constructed, so create_route bails.","triggerScenarios":"finalize_transit -> create_route where every stop id in route.stops failed create_stop (or was filtered out), leaving the filtered stops vec empty.","commonSituations":"Routes whose stops all lie outside the map boundary or near sidewalks that couldn't snap; partial GTFS imports where stop creation failed wholesale for a route; mismatched gtfs_id keys between stops and routes feeds.","solutions":["Fix the upstream stop-creation failures (see stop-level errors) so at least one stop resolves.","Check that route stop gtfs_ids match the ids in the stops feed (no key mismatch).","Skip the route (the importer does) or trim the GTFS feed to routes with importable stops."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let valid: Vec<_> = route.stops.iter()\n    .filter(|id| gtfs_to_stop_id.contains_key(*id)).count();\nif valid == 0 { /* skip route entirely before create_route */ }","typeGuard":null,"tryCatchPattern":"match create_route(...) {\n    Err(e) if e.to_string() == \"No valid stops\" => {\n        warn!(\"skipping route {:?}\", route.gtfs_id); Ok(None)\n    }\n    other => other.map(Some),\n}","preventionTips":["Fix stop-level import failures before importing routes","Cross-check gtfs_id keys between stops.txt and routes data","Import routes only after verifying at least one stop resolves"],"tags":["transit","gtfs","route-import"],"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"}