{"record":{"id":"c056a1f1eb3755de","repo":"a-b-street/abstreet","slug":"unexpected-topojson-contents","errorCode":null,"errorMessage":"Unexpected topojson contents","messagePattern":"Unexpected topojson contents","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"popgetter/src/lib.rs","lineNumber":104,"sourceCode":"        output.len()\n    );\n\n    Ok(output)\n}\n\nfn load_all_zones_as_geojson(path: &str) -> Result<Vec<Feature>> {\n    let mut start = Instant::now();\n    let topojson_str = fs_err::read_to_string(path)?;\n    println!(\"Reading file took {:?}\", start.elapsed());\n\n    start = Instant::now();\n    let topo = topojson_str.parse::<TopoJson>()?;\n    println!(\"Parsing topojson took {:?}\", start.elapsed());\n\n    start = Instant::now();\n    let fc = match topo {\n        TopoJson::Topology(t) => to_geojson(&t, \"zones\")?,\n        _ => bail!(\"Unexpected topojson contents\"),\n    };\n    println!(\"Converting to geojson took {:?}\", start.elapsed());\n\n    Ok(fc.features)\n}\n","sourceCodeStart":86,"sourceCodeEnd":110,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/popgetter/src/lib.rs#L86-L110","documentation":"load_all_zones_as_geojson parses a TopoJSON string and expects the TopJson::Topology variant so it can convert the \"zones\" object to GeoJSON; anything else (e.g. TopoJson::Geometry or a parse yielding another variant) bails with this fixed message. The tool assumes its popgetter-downloaded input is a TopoJSON Topology.","triggerScenarios":"Calling load_all_zones_as_geojson (popgetter/src/lib.rs:104) with a string that parses as TopoJson but is not a Topology — e.g. a plain GeoJSON file mislabeled as topojson, or a TopoJSON containing only bare geometry objects.","commonSituations":"Wrong download URL or cached file that is actually plain GeoJSON; file corruption truncating the Topology wrapper; API version change returning a different TopoJSON structure.","solutions":["Verify the input is real TopoJSON Topology (has a \"topology\" type / \"objects\" member) before calling.","Re-download the census zones from the popgetter source to replace the corrupted/mislabeled file.","If the input is actually GeoJSON, use the GeoJSON code path instead of the TopoJSON parser.","Check which object name is expected — the converter looks up the \"zones\" object; supply a Topology containing it."],"exampleFix":"// before: passing plain GeoJSON text\nlet zones = load_all_zones_as_geojson(geojson_str)?;\n// after: ensure TopoJSON topology\nassert!(topojson_str.contains(\"\\\"type\\\": \\\"Topology\\\"\"));\nlet zones = load_all_zones_as_geojson(topojson_str)?;","handlingStrategy":"validation","validationCode":"if !topojson_str.trim_start().contains(\"\\\"Topology\\\"\") && !topojson_str.contains(\"\\\"type\\\":\\\"Topology\\\"\") {\n    return Err(\"input is not a TopoJSON Topology\".into());\n}","typeGuard":"fn is_topology(parsed: &TopoJson) -> bool {\n    matches!(parsed, TopoJson::Topology(_))\n}","tryCatchPattern":"match load_all_zones_as_geojson(s) {\n    Err(e) if e == \"Unexpected topojson contents\" => {\n        // s was likely plain GeoJSON: parse via the GeoJSON path instead\n    }\n    other => other?,\n}","preventionTips":["Verify the download URL returns TopoJSON Topology (check for the \"Topology\"/\"objects\" wrapper).","Validate the file's shape after download and cache validity after API changes.","Fall back to a GeoJSON parser when the content is actually GeoJSON."],"tags":["topojson","geojson","popgetter","parsing"],"backgroundTag":"unexpected-response-shape","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"}