a-b-street/abstreet · error

URL doesn't seem to have query params

Error message

URL {url} doesn't seem to have query params

What it means

abstutil::parse_args on web reads arguments from the page URL's query string. It splits window.location.href on "?" and requires exactly one "?"; if there is no query string (or multiple "?"s), it bails with "URL ... doesn't seem to have query params". It is how web builds emulate CLI args.

Solutions

  1. Append the expected query parameters to the URL, e.g. https://host/path?map=/data/system/atwater.parcel_map.
  2. If arguments are optional, catch this error and fall back to defaults instead of failing.
  3. Sanitize generated URLs so they always include the query string, and avoid raw "?" in parameter values (use %3F).

Example fix

// before
let args = abstutil::cli_args();
// after
let args = abstutil::cli_args().unwrap_or_else(|_| vec!["--default".to_string()]);
Defensive patterns

Strategy: try-catch

Validate before calling

let has_query = web_sys::window()
    .and_then(|w| w.location().href().ok())
    .map(|href| href.contains('?'))
    .unwrap_or(false);

Try / catch

let args = abstutil::cli_args().unwrap_or_else(|_| {
    log::info!("no query params; using defaults");
    Vec::new()
});

Prevention

When it happens

Trigger: Loading the web app at a URL without any "?..." query string; URLs containing a "?" inside a fragment or more than one "?"; calling cli_args before the location is set.

Common situations: Opening the deployed app directly without appending parameters; broken links generated without the query portion; redirects stripping the query string.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/6dfcfd35dd399b5a. Report an issue: GitHub.

Appendix: source

Thrown at abstutil/src/cli.rs:57

    if result.is_empty() {
        result
    } else {
        format!("?{}", result)
    }
}

#[cfg(target_arch = "wasm32")]
fn parse_args() -> anyhow::Result<Vec<String>> {
    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()))
    })?;
    // Consider using a proper url parsing crate. This works fine for now, though.
    let url_parts = url.split("?").collect::<Vec<_>>();
    if url_parts.len() != 2 {
        bail!("URL {url} doesn't seem to have query params");
    }
    let parts = url_parts[1]
        .split("&")
        .map(|x| x.replace("%20", " ").to_string())
        .collect::<Vec<_>>();
    Ok(parts)
}

View on GitHub (pinned to 0964f29315)