a-b-street/abstreet · critical
Can't read
Error message
Can't read {}: {} What it means
slurp_bytes resolves a filename via the crate's environment-aware path() lookup and reads the whole file into memory. If slurp_file returns an error (missing file, permission denied, IO error), it panics with "Can't read {path}: {err}". This is an intentional abort: the caller asked for an asset the library assumes must exist (e.g. an SVG read by widgetry's settings).
Solutions
- Verify the file exists at the resolved path (abstio::path(filename) plus std::path::Path::exists) before calling slurp_bytes.
- Run the binary from the repo root or set the correct data directory so relative asset paths resolve.
- Use abstio::slurp_file with Result handling (or maybe_slurp) if a missing file is an expected, recoverable condition instead of slurp_bytes.
- Check file permissions and that packaging/deploy includes the asset files.
Example fix
// before
let bytes = abstio::slurp_bytes("icons/pin.svg");
// after
let path = abstio::path("icons/pin.svg");
if !std::path::Path::new(&path).exists() {
eprintln!("missing asset {}", path);
return;
}
let bytes = abstio::slurp_bytes("icons/pin.svg"); Defensive patterns
Strategy: validation
Validate before calling
let path = abstio::path("icons/pin.svg");
assert!(std::path::Path::new(&path).exists(), "missing asset: {}", path); Try / catch
// panics; cannot catch in Rust. Pre-check instead:
match abstio::slurp_file(&abstio::path(name)) {
Ok(bytes) => use(bytes),
Err(e) => eprintln!("skipping {}: {}", name, e),
} Prevention
- Run binaries from the repo root or set the data directory explicitly.
- Add asset existence checks in CI packaging steps.
- Prefer Result-returning slurp_file when a missing file is expected.
When it happens
Trigger: Calling abstio::slurp_bytes(filename) where path(filename) does not exist, is unreadable (permissions), or the underlying read fails with an IO error. Common with SVG assets passed to widgetry::Settings::read_svg.
Common situations: Running the app from the wrong working directory so relative asset paths don't resolve; a missing/misnamed SVG resource; deployment packaging that omitted asset files; permission-restricted data directories.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Couldn't read_json( )
- Couldn't read_binary
- Couldn't read_object
- Can't write_json( )
- Can't write_binary( )
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/ea3913807a30974c.
Report an issue: GitHub.
Appendix: source
Thrown at abstio/src/lib.rs:39
#[cfg(not(target_arch = "wasm32"))]
mod download;
#[cfg(not(target_arch = "wasm32"))]
pub use download::*;
pub use abst_data::*;
pub use abst_paths::*;
pub use http::*;
mod abst_data;
mod abst_paths;
mod http;
mod io;
/// An adapter for widgetry::Settings::read_svg to read SVGs using this crate's methods for finding
/// and reading files in different environments.
pub fn slurp_bytes(filename: &str) -> Vec<u8> {
let path = path(filename);
slurp_file(&path).unwrap_or_else(|err| panic!("Can't read {}: {}", path, err))
}
View on GitHub (pinned to 0964f29315)