{"record":{"id":"86c899e5a14d5a3e","repo":"tinyhumansai/openhuman","slug":"dns-resolution-task-failed-for-log-host-e","errorCode":null,"errorMessage":"DNS resolution task failed for '{log_host}': {e}","messagePattern":"DNS resolution task failed for '(.+?)': (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/tools/impl/network/url_guard.rs","lineNumber":163,"sourceCode":"\n    Ok(url)\n}\n\nasync fn resolve_host_ips(host: String, port: u16) -> anyhow::Result<Vec<IpAddr>> {\n    let log_host = host.clone();\n    tokio::task::spawn_blocking(move || {\n        (host.as_str(), port)\n            .to_socket_addrs()\n            .map_err(|e| {\n                log::debug!(\"[url_guard] DNS resolution failed host={host} port={port} error={e}\");\n                anyhow::anyhow!(\"DNS resolution failed for '{host}': {e}\")\n            })\n            .map(|iter| iter.map(|addr| addr.ip()).collect())\n    })\n    .await\n    .map_err(|e| {\n        log::debug!(\"[url_guard] DNS resolution task failed host={log_host} port={port} error={e}\");\n        anyhow::anyhow!(\"DNS resolution task failed for '{log_host}': {e}\")\n    })?\n}\n\npub(super) fn normalize_allowed_domains(domains: Vec<String>) -> Vec<String> {\n    if domains.is_empty() {\n        return Vec::new();\n    }\n    let mut normalized = domains\n        .into_iter()\n        .filter_map(|d| normalize_domain(&d))\n        .collect::<Vec<_>>();\n    normalized.sort_unstable();\n    normalized.dedup();\n    if normalized.is_empty() {\n        // All entries were malformed (whitespace-only, scheme-only, etc.) and\n        // filtered out. Returning empty would silently enter open mode; instead\n        // return a sentinel that keeps the tool in strict mode and rejects every\n        // URL — fail-closed on misconfiguration. (#2738)","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/tools/impl/network/url_guard.rs#L145-L181","documentation":"url_guard resolves DNS on a spawn_blocking thread; this fires when the JoinHandle itself fails — the blocking task panicked or was cancelled — as distinct from a resolver failure. It aborts SSRF validation before any request is issued.","triggerScenarios":"Thrown at src/openhuman/tools/impl/network/url_guard.rs:163 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Treat as transient infrastructure failure and retry the request","If persistent, investigate the panic in the blocking resolver path"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}