{"record":{"id":"fd298db872ba58a8","repo":"a-b-street/abstreet","slug":"can-t-slurp-file-it-doesn-t-exist","errorCode":null,"errorMessage":"Can't slurp_file {}, it doesn't exist","messagePattern":"Can't slurp_file (.+?), it doesn't exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"abstio/src/io_web.rs","lineNumber":101,"sourceCode":"\npub fn slurp_file<I: AsRef<str>>(path: I) -> Result<Vec<u8>> {\n    let path = path.as_ref();\n\n    if let Some(raw) = SYSTEM_DATA.get_file(path.trim_start_matches(\"../data/system/\")) {\n        Ok(raw.contents().to_vec())\n    } else if path.starts_with(&path_player(\"\")) {\n        let string = read_local_storage(path)?;\n        // TODO Hack: if it probably wasn't written with write_json, do the base64 decoding. This\n        // may not always be appropriate...\n        if path.ends_with(\".json\") {\n            Ok(string.into_bytes())\n        } else {\n            use base64::Engine;\n            let bytes = base64::engine::general_purpose::STANDARD.decode(string)?;\n            Ok(bytes)\n        }\n    } else {\n        bail!(\"Can't slurp_file {}, it doesn't exist\", path)\n    }\n}\n\npub fn maybe_read_binary<T: DeserializeOwned>(path: String, _: &mut Timer) -> Result<T> {\n    if let Some(raw) = SYSTEM_DATA.get_file(path.trim_start_matches(\"../data/system/\")) {\n        bincode::deserialize(raw.contents()).map_err(|err| err.into())\n    } else if path.starts_with(&path_player(\"\")) {\n        let string = read_local_storage(&path)?;\n        use base64::Engine;\n        let out = bincode::deserialize(&base64::engine::general_purpose::STANDARD.decode(string)?)?;\n        Ok(out)\n    } else {\n        bail!(\"Can't maybe_read_binary {}, it doesn't exist\", path)\n    }\n}\n\npub fn write_json<T: Serialize>(path: String, obj: &T) {\n    // Only save for data/player, for now","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/abstio/src/io_web.rs#L83-L119","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet raw = abstio::slurp_file(\"../data/system/missing.json\", timer)?;\n// after\nif abstio::file_exists(\"../data/system/missing.json\") {\n    let raw = abstio::slurp_file(\"../data/system/missing.json\", timer)?;\n} else {\n    bail!(\"expected input is missing from the web bundle\");\n}","handlingStrategy":"fallback","validationCode":"if !abstio::file_exists(path) {\n    bail!(\"{} missing from web bundle\", path);\n}","typeGuard":null,"tryCatchPattern":"match abstio::slurp_file(path, timer) {\n    Ok(raw) => raw,\n    Err(_) => include_fallback_bytes(), // e.g. embedded default asset\n}","preventionTips":["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)."],"tags":["web","wasm","file-not-found"],"backgroundTag":"file-not-found","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"}