{"record":{"id":"46dde354982aa74e","repo":"getzola/zola","slug":"could-not-parse-domain-from-link","errorCode":null,"errorMessage":"could not parse domain `{}` from link","messagePattern":"could not parse domain `(.+?)` from link","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"components/site/src/link_checking.rs","lineNumber":123,"sourceCode":"        );\n    }\n    messages\n}\n\nfn should_skip_by_prefix(link: &str, skip_prefixes: &[String]) -> bool {\n    skip_prefixes.iter().any(|prefix| link.starts_with(prefix))\n}\n\nfn should_skip_by_file(file_path: &Path, glob_set: &GlobSet) -> bool {\n    glob_set.is_match(file_path)\n}\n\nfn get_link_domain(link: &str) -> Result<String> {\n    match Url::parse(link) {\n        Ok(url) => match url.host_str().map(String::from) {\n            Some(domain_str) => Ok(domain_str),\n            None => bail!(\"could not parse domain `{}` from link\", link),\n        },\n        Err(err) => bail!(\"could not parse domain `{}` from link: `{}`\", link, err),\n    }\n}\n\n/// Checks all external links and returns all the errors that were encountered.\n/// Empty vec == all good\npub fn check_external_links(site: &Site) -> Vec<String> {\n    struct LinkDef {\n        file_path: PathBuf,\n        external_link: String,\n        domain: String,\n    }\n\n    impl LinkDef {\n        pub fn new(file_path: &Path, external_link: &str, domain: String) -> Self {\n            Self {\n                file_path: file_path.to_path_buf(),\n                external_link: external_link.to_string(),","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/components/site/src/link_checking.rs#L105-L141","documentation":"`get_link_domain` parses an external link URL and extracts its host. When the URL parses successfully but has no host component (e.g. a relative or scheme-only URL such as `mailto:` or `data:`), the function bails with this message. It is used by `check_external_links` to group/validate external links by domain.","triggerScenarios":"Calling `get_link_domain` with a link that `Url::parse` accepts but whose `url.host_str()` is None: scheme-only URLs like `mailto:user@example.com`, `tel:+123`, `data:...`, or protocol-relative/weird inputs that the url crate parses without a host.","commonSituations":"Site content contains `mailto:` or `tel:` links, anchor-only or data-URI links, or feed/generated links without an authority; the link checker treats them as unparseable domains.","solutions":["Filter out non-http(s) links before calling `get_link_domain` (skip `mailto:`, `tel:`, `data:`, anchors)","Check that the link contains a host before parsing, e.g. starts with http:// or https://","If the link is genuinely malformed, fix the content file where the link is defined"],"exampleFix":"// before\nlet domain = get_link_domain(link)?;\n// after\nif link.starts_with(\"mailto:\") || link.starts_with(\"tel:\") { continue; }\nlet domain = get_link_domain(link)?;","handlingStrategy":"validation","validationCode":"fn is_external_http_link(link: &str) -> bool {\n    matches!(Url::parse(link), Ok(ref u) if matches!(u.scheme(), \"http\" | \"https\") && u.host_str().is_some())\n}","typeGuard":"fn has_host(url: &Url) -> bool { url.host_str().is_some() }","tryCatchPattern":"match get_link_domain(link) {\n    Ok(domain) => check(domain),\n    Err(_) => skipped_links.push(link.to_string()), // ignore non-domain links\n}","preventionTips":["Skip mailto:/tel:/data:/anchor links before domain extraction","Only pass absolute http(s) URLs to get_link_domain","Unit-test the link pipeline with scheme-only URLs"],"tags":["rust","url-parsing","link-checker"],"backgroundTag":"url-parse-failed","analyzedSha":"61d30828217957120309db657950224edf9707e2","analyzedAt":"2026-09-03T14:39:09.727Z","contentChangedAt":"2026-09-03T14:39:09.727Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}