a-b-street/abstreet · warning · anyhow::Error
window.history failed
Error message
window.history failed
What it means
update_url calls window.history() to obtain the History object for pushState-style URL rewriting. If the JS call throws, this error is thrown with the JS message or the 'window.history failed' fallback.
Solutions
- Remove restrictive sandbox attributes on the containing iframe
- Test in a standard browser to confirm History API works
- Catch and degrade gracefully: skip URL rewriting when history is unavailable
Example fix
// before: unconditional URL update
must_update_url(ctx, transform);
// after: tolerate missing history
if web_sys::window().map(|w| w.history().is_ok()).unwrap_or(false) {
must_update_url(ctx, transform);
} Defensive patterns
Strategy: fallback
Validate before calling
let history_ok = web_sys::window().map(|w| w.history().is_ok()).unwrap_or(false);
if !history_ok { log::warn!("History API unavailable; skipping URL update"); } Type guard
fn history_available(w: &web_sys::Window) -> bool { w.history().is_ok() } Try / catch
match window.history() {
Ok(h) => { /* replace_state flow */ }
Err(e) => log::warn!("history unavailable: {:?}; URL not updated", e.as_string()),
} Prevention
- Avoid fully sandboxed iframes if the app needs URL rewriting
- Treat History API as optional; make URL updates non-fatal
- Verify History API support in embedded webviews used for testing
When it happens
Trigger: window.history() throwing: rare, but occurs in sandboxed iframes where the History API is restricted, or in non-standard/embedded webviews lacking a History implementation.
Common situations: Sandboxed iframe without allow-same-origin, restricted webview environments, browser extensions stripping History API.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- no window?
- window.location.href failed
- window.history.replace_state failed
- no window?
- local_storage failed
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/5b599a7cef05fa45.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/tools/url.rs:120
}
#[allow(unused_variables)]
fn update_url(transform: Box<dyn Fn(String) -> String>) -> Result<()> {
#[cfg(target_arch = "wasm32")]
{
let window = web_sys::window().ok_or(anyhow!("no window?"))?;
let url = window.location().href().map_err(|err| {
anyhow!(err
.as_string()
.unwrap_or("window.location.href failed".to_string()))
})?;
let new_url = (transform)(url);
// Setting window.location.href may seem like the obvious thing to do, but that actually
// refreshes the page. This method just changes the URL and doesn't mess up history. See
// https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API.
let history = window.history().map_err(|err| {
anyhow!(err
.as_string()
.unwrap_or("window.history failed".to_string()))
})?;
history
.replace_state_with_url(&wasm_bindgen::JsValue::NULL, "", Some(&new_url))
.map_err(|err| {
anyhow!(err
.as_string()
.unwrap_or("window.history.replace_state failed".to_string()))
})?;
}
Ok(())
}
fn change_url_free_param(url: String, free_param: &str) -> String {
// The URL parsing crates I checked had lots of dependencies and didn't even expose such a nice
// API for doing this anyway.
let url_parts = url.split('?').collect::<Vec<_>>();View on GitHub (pinned to 0964f29315)