a-b-street/abstreet · warning · anyhow::Error
missing from local storage
Error message
{} missing from local storage What it means
read_local_storage returns this error when storage.get_item(&path) succeeds but yields None, i.e. the requested key does not exist in localStorage. The message includes the path so the developer knows which key was missing. This is the normal 'not found' outcome of the localStorage API surfaced as an anyhow error.
Solutions
- Use maybe_read_binary / handle the Err to supply a default value on first run
- Seed localStorage (or write defaults) before reading
- Verify the exact key path matches what write_raw/write_binary stored
- Persist important data server-side or in IndexedDB instead of localStorage to survive storage clears
Example fix
// before let raw = abstio::slurp_file(path).unwrap(); // panics on first run // after let raw = abstio::maybe_read_binary(path).unwrap_or_else(|| default_bytes());
Defensive patterns
Strategy: fallback
Validate before calling
// check existence before reading
let exists = web_sys::window().unwrap()
.local_storage().unwrap().unwrap()
.get_item(path).unwrap().is_some(); Try / catch
let raw = slurp_file(path).unwrap_or_else(|_| default_contents());
Prevention
- Use maybe_read_binary to express 'optional' reads idiomatically
- Seed defaults on first run instead of assuming prior writes
- Keep key paths centralized so write/read paths never drift
- Don't rely on localStorage for durable data — it is per-origin and clearable
When it happens
Trigger: Calling abstio::slurp_file or maybe_read_binary for a path that was never written to localStorage on this origin/browser profile, or after the user cleared site data; also when the key name casing/format differs from what write_raw stored.
Common situations: First run of the app before any save; user cleared browser storage; reading a key written under a different path prefix/version; data lost because localStorage is per-origin and per-browser-profile.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- set_item for failed for encoded length
- no window?
- local_storage failed
- no local_storage?
- get_item failed
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/d5cfed0498a57cc6.
Report an issue: GitHub.
Appendix: source
Thrown at abstio/src/io_web.rs:178
let window = web_sys::window().unwrap();
let storage = window.local_storage().unwrap().unwrap();
storage.remove_item(path).unwrap();
}
fn read_local_storage(path: &str) -> Result<String> {
let window = web_sys::window().ok_or(anyhow!("no window?"))?;
let storage = window
.local_storage()
.map_err(|err| {
anyhow!(err
.as_string()
.unwrap_or("local_storage failed".to_string()))
})?
.ok_or(anyhow!("no local_storage?"))?;
let string = storage
.get_item(&path)
.map_err(|err| anyhow!(err.as_string().unwrap_or("get_item failed".to_string())))?
.ok_or(anyhow!("{} missing from local storage", path))?;
Ok(string)
}
fn list_local_storage_keys() -> Vec<String> {
let window = web_sys::window().unwrap();
let storage = window.local_storage().unwrap().unwrap();
let mut keys = Vec::new();
for idx in 0..storage.length().unwrap() {
keys.push(storage.key(idx).unwrap().unwrap());
}
keys
}
/// Returns path on success
pub fn write_file(path: String, contents: String) -> Result<String> {
// Make the browser prompt the user to save a local file with arbitrary contents.
use wasm_bindgen::JsCast;
View on GitHub (pinned to 0964f29315)