{"record":{"id":"18f83200522a47a7","repo":"SeleniumHQ/selenium","slug":"error-parsing-json-from-url","errorCode":null,"errorMessage":"Error parsing JSON from URL {} {}","messagePattern":"Error parsing JSON from URL (.+?) (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"rust/src/downloads.rs","lineNumber":108,"sourceCode":"pub async fn read_redirect_from_link(\n    http_client: &Client,\n    url: String,\n    log: &Logger,\n) -> Result<String, Error> {\n    parse_version(\n        http_client.get(&url).send().await?.url().path().to_string(),\n        log,\n    )\n}\n\npub fn parse_json_from_url<T>(http_client: &Client, url: &str) -> Result<T, Error>\nwhere\n    T: Serialize + for<'a> Deserialize<'a>,\n{\n    let content = read_content_from_link(http_client, url)?;\n    match serde_json::from_str(&content) {\n        Ok(json) => Ok(json),\n        Err(err) => Err(anyhow!(format!(\n            \"Error parsing JSON from URL {} {}\",\n            url, err\n        ))),\n    }\n}\n","sourceCodeStart":90,"sourceCodeEnd":114,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rust/src/downloads.rs#L90-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Manually fetch the URL and confirm the body is valid JSON matching the expected schema.","Retry to rule out a transient partial response.","Check for proxy/TLS interception that rewrites the body.","If the upstream schema changed, update the deserializing struct T."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Rust: validate JSON shape before deserializing into the typed struct\nlet content = read_content_from_link(http_client, url)?;\nlet v: serde_json::Value = serde_json::from_str(&content)\n    .map_err(|e| anyhow!(\"Endpoint {} returned non-JSON: {}\", url, e))?;","typeGuard":null,"tryCatchPattern":"match parse_json_from_url::<T>(http_client, url) {\n    Ok(data) => Ok(data),\n    Err(e) if e.to_string().contains(\"Error parsing JSON\") => {\n        log::warn!(\"Version endpoint {} returned malformed JSON; falling back\", url);\n        fallback_discovery()\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Log the raw body when JSON parsing fails for diagnosis.","Pin the deserializing structs to the documented API schema.","Detect HTML/error pages before attempting JSON parse."],"tags":["rust","selenium-manager","network","json","serde","download"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}