{"record":{"id":"f8f9e09635a5142c","repo":"a-b-street/abstreet","slug":"window-location-href-failed","errorCode":null,"errorMessage":"window.location.href failed","messagePattern":"window\\.location\\.href failed","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"abstutil/src/cli.rs","lineNumber":50,"sourceCode":"    // TODO Similar to parse_args forgoing a URL decoding crate, just handle this one\n    // transformation\n    let result = args\n        .into_iter()\n        .map(|x| x.replace(\" \", \"%20\"))\n        .collect::<Vec<_>>()\n        .join(\"&\");\n    if result.is_empty() {\n        result\n    } else {\n        format!(\"?{}\", result)\n    }\n}\n\n#[cfg(target_arch = \"wasm32\")]\nfn parse_args() -> anyhow::Result<Vec<String>> {\n    let window = web_sys::window().ok_or(anyhow!(\"no window?\"))?;\n    let url = window.location().href().map_err(|err| {\n        anyhow!(err\n            .as_string()\n            .unwrap_or(\"window.location.href failed\".to_string()))\n    })?;\n    // Consider using a proper url parsing crate. This works fine for now, though.\n    let url_parts = url.split(\"?\").collect::<Vec<_>>();\n    if url_parts.len() != 2 {\n        bail!(\"URL {url} doesn't seem to have query params\");\n    }\n    let parts = url_parts[1]\n        .split(\"&\")\n        .map(|x| x.replace(\"%20\", \" \").to_string())\n        .collect::<Vec<_>>();\n    Ok(parts)\n}\n","sourceCodeStart":32,"sourceCodeEnd":65,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/abstutil/src/cli.rs#L32-L65","documentation":"After obtaining the window, parse_args calls window.location().href(), which returns a Result whose Err case is a JsValue. The code converts the JsValue to a String; if it is not a string (or is empty) it falls back to the literal message \"window.location.href failed\". This wraps a JS-side failure of the href property access into an anyhow error.","triggerScenarios":"Calling cli_args() in a browser when reading location.href throws or returns a rejected JsValue — rare, but possible if the document origin/context is detached (e.g. window closed, about:blank in some sandboxed iframes, or the JsValue error is not a string).","commonSituations":"Sandboxed iframes with restricted navigation APIs; running inside a partially torn-down page; embedding the app in an environment where Location access is blocked by the host page.","solutions":["Log the raw JsValue in the browser console to see the underlying JS error","Verify the page origin allows reading location.href (avoid exotic sandbox attributes)","Consider wrapping with js_sys::Error to extract a better message than the fallback string","Fall back to window.location.search which is less likely to fail if only the query string is needed"],"exampleFix":"// before\nanyhow!(err.as_string().unwrap_or(\"window.location.href failed\".to_string()))\n// after\nlet msg = err.as_string().unwrap_or_else(|| format!(\"window.location.href failed: {:?}\", err));\nErr(anyhow!(msg))","handlingStrategy":"try-catch","validationCode":"// ensure location is readable\nlet ok = web_sys::window().map(|w| !w.location().href().is_err()).unwrap_or(false);","typeGuard":null,"tryCatchPattern":"match cli_args() {\n    Ok(args) => use(args),\n    Err(e) => {\n        log::error!(\"failed to read URL args: {:?}\", e);\n        default_args()\n    }\n}","preventionTips":["Avoid exotic sandboxed iframe setups when embedding the app","Prefer window.location.search for query strings only","Log raw JsValue errors in the console during development"],"tags":["wasm","browser-api","web-sys","url"],"backgroundTag":"http-request-failed","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"}