a-b-street/abstreet · error
Can't slurp_file , it doesn't exist
Error message
Can't slurp_file {}, it doesn't exist What it means
On the web (wasm) target, abstio::slurp_file reads files from the bundled SYSTEM_DATA archive or localStorage. If the requested path is not present in the embedded archive, it bails with "Can't slurp_file ..., it doesn't exist". Native filesystem reads do not apply here.
Solutions
- Check the path spelling and that the file exists in the data/system directory included in the web build.
- Rebuild/refresh the web bundle so the missing file is embedded in SYSTEM_DATA.
- For player-generated files (data/player/*), use the local-storage-backed read path appropriate for web.
Example fix
// before
let raw = abstio::slurp_file("../data/system/missing.json", timer)?;
// after
if abstio::file_exists("../data/system/missing.json") {
let raw = abstio::slurp_file("../data/system/missing.json", timer)?;
} else {
bail!("expected input is missing from the web bundle");
} Defensive patterns
Strategy: fallback
Validate before calling
if !abstio::file_exists(path) {
bail!("{} missing from web bundle", path);
} Try / catch
match abstio::slurp_file(path, timer) {
Ok(raw) => raw,
Err(_) => include_fallback_bytes(), // e.g. embedded default asset
} Prevention
- Rebuild the web bundle whenever data/system files change.
- Check file_exists before reading optional assets.
- Use exact, case-correct paths matching the bundle keys (../data/system/ prefix trimmed).
When it happens
Trigger: Requesting a path on web that wasn't included in the system data bundle at build time; a path that doesn't match the trimmed key (paths are stripped of the ../data/system/ prefix); reading player-saved files through slurp_file instead of the player storage API.
Common situations: Adding new data files to the repo without rebuilding the web bundle; typos in the path or case-sensitivity differences; trying to read a user-generated file that only lives in localStorage.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Can't maybe_read_binary
- Not saving
- Don't know MIME type for
- Unsupported on web
- URL doesn't seem to have query params
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/fd298db872ba58a8.
Report an issue: GitHub.
Appendix: source
Thrown at abstio/src/io_web.rs:101
pub fn slurp_file<I: AsRef<str>>(path: I) -> Result<Vec<u8>> {
let path = path.as_ref();
if let Some(raw) = SYSTEM_DATA.get_file(path.trim_start_matches("../data/system/")) {
Ok(raw.contents().to_vec())
} else if path.starts_with(&path_player("")) {
let string = read_local_storage(path)?;
// TODO Hack: if it probably wasn't written with write_json, do the base64 decoding. This
// may not always be appropriate...
if path.ends_with(".json") {
Ok(string.into_bytes())
} else {
use base64::Engine;
let bytes = base64::engine::general_purpose::STANDARD.decode(string)?;
Ok(bytes)
}
} else {
bail!("Can't slurp_file {}, it doesn't exist", path)
}
}
pub fn maybe_read_binary<T: DeserializeOwned>(path: String, _: &mut Timer) -> Result<T> {
if let Some(raw) = SYSTEM_DATA.get_file(path.trim_start_matches("../data/system/")) {
bincode::deserialize(raw.contents()).map_err(|err| err.into())
} else if path.starts_with(&path_player("")) {
let string = read_local_storage(&path)?;
use base64::Engine;
let out = bincode::deserialize(&base64::engine::general_purpose::STANDARD.decode(string)?)?;
Ok(out)
} else {
bail!("Can't maybe_read_binary {}, it doesn't exist", path)
}
}
pub fn write_json<T: Serialize>(path: String, obj: &T) {
// Only save for data/player, for nowView on GitHub (pinned to 0964f29315)