{"record":{"id":"290b4283aa9c232a","repo":"a-b-street/abstreet","slug":"couldn-t-read-binary","errorCode":null,"errorMessage":"Couldn't read_binary({}): {}","messagePattern":"Couldn't read_binary\\((.+?)\\): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"abstio/src/io.rs","lineNumber":33,"sourceCode":"    timer.start(format!(\"parse {}\", path));\n    // TODO timer.read_file isn't working here. And we need to call stop() if there's no file.\n    let result: Result<T> =\n        slurp_file(&path).and_then(|raw| serde_json::from_slice(&raw).map_err(|err| err.into()));\n    timer.stop(format!(\"parse {}\", path));\n    result\n}\n\npub fn read_json<T: DeserializeOwned>(path: String, timer: &mut Timer) -> T {\n    match maybe_read_json(path.clone(), timer) {\n        Ok(obj) => obj,\n        Err(err) => panic!(\"Couldn't read_json({}): {}\", path, err),\n    }\n}\n\npub fn read_binary<T: DeserializeOwned>(path: String, timer: &mut Timer) -> T {\n    match maybe_read_binary(path.clone(), timer) {\n        Ok(obj) => obj,\n        Err(err) => panic!(\"Couldn't read_binary({}): {}\", path, err),\n    }\n}\n\n/// May be a JSON or binary file\npub fn read_object<T: DeserializeOwned>(path: String, timer: &mut Timer) -> Result<T> {\n    if path.ends_with(\".bin\") {\n        maybe_read_binary(path, timer)\n    } else {\n        maybe_read_json(path, timer)\n    }\n}\n\n/// May be a JSON or binary file. Panics on failure.\npub fn must_read_object<T: DeserializeOwned>(path: String, timer: &mut Timer) -> T {\n    match read_object(path.clone(), timer) {\n        Ok(obj) => obj,\n        Err(err) => panic!(\"Couldn't read_object({}): {}\", path, err),\n    }","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/abstio/src/io.rs#L15-L51","documentation":"read_binary loads a bincode-serialized file (path must end with .bin) and deserializes it into T. On any failure it panics with this message instead of returning a Result. Failures come from maybe_read_binary: a missing/unreadable file, a Timer I/O error, or bincode deserialization failure (corrupt or wrong-type data). Use maybe_read_binary if you need recoverable errors.","triggerScenarios":"Calling read_binary(path, timer) where the path does not exist or is unreadable; the path does not end with '.bin' (maybe_read_binary panics on that separately); the file's bytes are not valid bincode or do not match T (schema/format mismatch); the file was truncated or produced by a different bincode configuration.","commonSituations":"Pointing at a JSON file with a .bin name or vice versa; stale .bin files left over after data-format changes between versions; partially written or corrupted .bin files from an interrupted run; passing a path relative to the wrong working directory.","solutions":["Verify the path exists and ends with .bin (use abstio::file_exists before calling).","If the file may be absent or corrupt, call maybe_read_binary and handle the Err instead of read_binary.","Regenerate the .bin file with the current write_binary / data schema; stale or corrupt files must be rebuilt.","Check that the bincode version/config matches whatever wrote the file, and that T matches the serialized type."],"exampleFix":"// before\nlet map = abstio::read_binary::<Map>(\"data/map.bin\".to_string(), &mut timer);\n\n// after\nlet map = match abstio::maybe_read_binary::<Map>(\"data/map.bin\".to_string(), &mut timer) {\n    Ok(m) => m,\n    Err(err) => {\n        eprintln!(\"falling back: {}\", err);\n        build_default_map(&mut timer)\n    }\n};","handlingStrategy":"fallback","validationCode":"if !abstio::file_exists(&path) || !path.ends_with(\".bin\") {\n    eprintln!(\"{} missing or not a .bin file; using fallback\", path);\n}","typeGuard":"fn is_bin_path(path: &str) -> bool {\n    path.ends_with(\".bin\") && std::path::Path::new(path).is_file()\n}","tryCatchPattern":"// Rust panics can be caught, but prefer the Result API:\nmatch abstio::maybe_read_binary::<T>(path.clone(), &mut timer) {\n    Ok(obj) => obj,\n    Err(err) => { eprintln!(\"read_binary failed: {}\", err); fallback() }\n}","preventionTips":["Prefer maybe_read_binary (Result) over read_binary whenever the file may be absent or corrupt.","Always check the extension is .bin before calling.","Regenerate .bin artifacts whenever the data schema or bincode version changes.","Use write_binary so files are written atomically-enough; avoid killing processes mid-write."],"tags":["rust","panic","deserialization","file-io"],"backgroundTag":"file-read-failed","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"}