SeleniumHQ/selenium · error · anyhow::Error

Error parsing JSON from URL

Error message

Error parsing JSON from URL {} {}

What it means

Raised by parse_json_from_url() in rust/src/downloads.rs when serde_json::from_str fails on the body fetched from a URL. This wraps the serde error and the URL so the caller knows which endpoint returned malformed JSON. It is used to parse version-discovery endpoints (CfT, NuGet, msedgedriver) and any deserialization failure is fatal for that discovery path.

Solutions

  1. Manually fetch the URL and confirm the body is valid JSON matching the expected schema.
  2. Retry to rule out a transient partial response.
  3. Check for proxy/TLS interception that rewrites the body.
  4. If the upstream schema changed, update the deserializing struct T.
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: validate JSON shape before deserializing into the typed struct
let content = read_content_from_link(http_client, url)?;
let v: serde_json::Value = serde_json::from_str(&content)
    .map_err(|e| anyhow!("Endpoint {} returned non-JSON: {}", url, e))?;

Try / catch

match parse_json_from_url::<T>(http_client, url) {
    Ok(data) => Ok(data),
    Err(e) if e.to_string().contains("Error parsing JSON") => {
        log::warn!("Version endpoint {} returned malformed JSON; falling back", url);
        fallback_discovery()
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: read_content_from_link returns successfully but the text is not valid JSON for the expected type T. Causes: endpoint returns HTML error page, a truncated response, a schema mismatch where the JSON doesn't fit T, or a 200 with an empty body.

Common situations: A version endpoint is temporarily replaced by a maintenance HTML page; corporate proxy injects a block page; the upstream API schema changed; TLS interception corrupts the body.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/18f83200522a47a7. Report an issue: GitHub.

Appendix: source

Thrown at rust/src/downloads.rs:108

pub async fn read_redirect_from_link(
    http_client: &Client,
    url: String,
    log: &Logger,
) -> Result<String, Error> {
    parse_version(
        http_client.get(&url).send().await?.url().path().to_string(),
        log,
    )
}

pub fn parse_json_from_url<T>(http_client: &Client, url: &str) -> Result<T, Error>
where
    T: Serialize + for<'a> Deserialize<'a>,
{
    let content = read_content_from_link(http_client, url)?;
    match serde_json::from_str(&content) {
        Ok(json) => Ok(json),
        Err(err) => Err(anyhow!(format!(
            "Error parsing JSON from URL {} {}",
            url, err
        ))),
    }
}

View on GitHub (pinned to aa36b38e69)