a-b-street/abstreet · error · anyhow::Error
no window?
Error message
no window?
What it means
In the title screen's process-replacement logic (map_gui), the wasm-only helper set_href obtains the browser Window via web_sys::window() and errors with anyhow!("no window?") if absent, since navigating requires a real window. It is the same guard as abstutil's parse_args but for navigation.
Solutions
- Only trigger title-screen navigation from a browser main thread
- Provide a window shim or stub in test/worker environments
- Skip or mock the navigation step when web_sys::window() returns None
Example fix
// before
let window = web_sys::window().ok_or(anyhow!("no window?"))?;
// after
let Some(window) = web_sys::window() else {
log::warn!("no window; skipping navigation to {}", url);
return Ok(());
}; Defensive patterns
Strategy: type-guard
Validate before calling
if web_sys::window().is_none() {
return; // cannot navigate outside a browser
} Type guard
fn can_navigate() -> bool { web_sys::window().is_some() } Try / catch
if let Err(e) = set_href(url) {
log::warn!("navigation failed: {:?}", e);
} Prevention
- Trigger title-screen navigation only from user events in a browser
- Stub set_href in tests and workers
- Gate cfg(wasm32) navigation behind a window availability check
When it happens
Trigger: Clicking a title-screen button on web (replace_process) in an environment where window is unavailable — headless wasm tests, workers, or non-browser runtimes.
Common situations: Running the GUI's wasm build in Node or a test harness; web worker without window shim; automation without DOM.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- no window?
- window.location.href failed
- window.location.set_href failed
- unable to cast to WebGl2RenderingContext. error
- no window?
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/804920cc3c4f2658.
Report an issue: GitHub.
Appendix: source
Thrown at map_gui/src/tools/title_screen.rs:241
let err = Command::new(binary).args(args).exec();
// We only get here if something broke
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));View on GitHub (pinned to 0964f29315)