a-b-street/abstreet · error · anyhow::Error
window.location.set_href failed
Error message
window.location.set_href failed
What it means
set_href calls window.location().set_href(url), which returns a Result<JsValue> that resolves after the browser attempts navigation; failure is a JsValue converted with as_string(), falling back to "window.location.set_href failed" if the error isn't a string. This means the browser refused the navigation request.
Solutions
- Verify the URL is absolute and well-formed (include https:// scheme)
- Ensure the iframe sandbox permits top navigation (allow-top-navigation) or open in a new tab with window.open instead
- Check browser console for the underlying JS error
- Avoid building URLs with unencoded special characters
Example fix
// before
set_href("abst://myapp")?;
// after
set_href("https://abstreet.org/myapp.html")?; Defensive patterns
Strategy: try-catch
Validate before calling
// validate the URL before navigation
new URL(url); // throws in JS if malformed
if (!url.startsWith('http')) throw new Error('set_href needs an absolute URL'); Try / catch
match set_href(url) {
Ok(_) => {},
Err(e) => log::error!("set_href failed: {:?}", e), // inspect browser console too
} Prevention
- Always navigate to absolute, well-formed URLs
- Avoid iframe sandbox attributes that block top navigation
- Test embedded deployments (iframes) separately from top-level pages
When it happens
Trigger: Calling set_href with a URL the browser blocks: invalid URL format, cross-origin navigation blocked in sandboxed iframes, or a popup/iframe sandbox without allow-top-navigation.
Common situations: App embedded in a sandboxed iframe attempting top-level navigation; malformed hand-built URL (missing scheme); browser extension or CSP blocking navigation.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- window.location.href failed
- no window?
- no window?
- window.location.href failed
- Can't slurp_file , it doesn't exist
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/bd1026fa137248aa.
Report an issue: GitHub.
Appendix: source
Thrown at map_gui/src/tools/title_screen.rs:243
Transition::Push(PopupMsg::new_state(ctx, "Error", vec![err.to_string()]))
}
// On Windows, all we can do is open a new child process. Not sure how to end the
// current or detach.
#[cfg(windows)]
{
abstutil::must_run_cmd(Command::new(binary).args(args));
Transition::Keep
}
}
// On web, leave the current page and go to another.
#[cfg(target_arch = "wasm32")]
{
fn set_href(url: &str) -> anyhow::Result<()> {
let window = web_sys::window().ok_or(anyhow!("no window?"))?;
window.location().set_href(url).map_err(|err| {
anyhow!(err
.as_string()
.unwrap_or("window.location.set_href failed".to_string()))
})
}
let page = match self {
Executable::ABStreet => "abstreet",
Executable::FifteenMin => "fifteen_min",
Executable::OSMViewer => "osm_viewer",
// This only works on native
Executable::ParkingMapper => unreachable!(),
Executable::Santa => "santa",
Executable::RawMapEditor => "map_editor",
Executable::LTN => "ltn",
};
let url = format!("{}.html{}", page, abstutil::args_to_query_string(args));
if let Err(err) = set_href(&url) {
return Transition::Push(PopupMsg::new_state(View on GitHub (pinned to 0964f29315)