{"record":{"id":"28fa07eedc0f50fb","repo":"tw93/Pake","slug":"web-urls-must-have-a-host","errorCode":null,"errorMessage":"web URLs must have a host","messagePattern":"web URLs must have a host","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/app/window.rs","lineNumber":743,"sourceCode":"                    eprintln!(\"[Pake] Failed to retain the macOS window for tabbing.\");\n                    return;\n                };\n                ns_window.setTabbingMode(objc2_app_kit::NSWindowTabbingMode::Preferred);\n            },\n            Err(error) => {\n                eprintln!(\"[Pake] Failed to access the macOS window for tabbing: {error}\");\n            }\n        });\n    }\n\n    // WKWebView does not show an HTTP Basic login dialog and ignores Chromium's\n    // certificate-error flag. Install one host-scoped delegate for both flows\n    // on the process-lifetime main window, then navigate to the real target.\n    #[cfg(target_os = \"macos\")]\n    if let Some(target_url) = auth_target {\n        let allowed_host = target_url\n            .host_str()\n            .expect(\"web URLs must have a host\")\n            .to_owned();\n        let prompt_for_basic_auth = config.basic_auth;\n        let allow_invalid_certificates = window_config.ignore_certificate_errors;\n        let auth_window = window.clone();\n        Queue::main().exec_async(move || {\n            if let Err(error) = auth_window.with_webview(move |webview| {\n                if !crate::app::auth::install_auth_delegate_and_navigate(\n                    webview.inner(),\n                    allowed_host,\n                    target_url.to_string(),\n                    prompt_for_basic_auth,\n                    allow_invalid_certificates,\n                ) {\n                    eprintln!(\"[Pake] Failed to configure macOS authentication handling.\");\n                }\n            }) {\n                eprintln!(\"[Pake] Failed to access the macOS webview: {error}\");\n            }","sourceCodeStart":725,"sourceCodeEnd":761,"githubUrl":"https://github.com/tw93/Pake/blob/777dd552ade5fd49c96cf4cbab73312eba1011db/src-tauri/src/app/window.rs#L725-L761","documentation":"This is a Rust `.expect(...)` panic on `target_url.host_str()` in the macOS auth delegate setup in `build_window` (src-tauri/src/app/window.rs:743). The `url` crate returns `None` for `host_str()` when a URL has no host component (e.g. `about:blank`, `data:` URIs, or relative references), and the assertion assumes every auth target is a real web URL with a host. If an auth-target URL without a host reaches this line, the process panics instead of degrading gracefully.","triggerScenarios":"`auth_target` is `Some(...)` on macOS AND the target URL lacks a host — i.e. the URL passed to `build_window` (via `open_requested_window` / `build_window_with_label`) is a scheme-only or opaque URL such as `about:blank`, `data:text/html,...`, `javascript:...`, or a malformed string that still parsed but has no authority component.","commonSituations":"Developers hit this when packaging an app whose start URL is not an `http(s)` web URL (a `data:` or custom-scheme page), when a config file or CLI flag supplies an empty/scheme-only value that gets coerced into an auth flow, or when wiring basic-auth/certificate-error handling around a local file or custom-protocol URL that legitimately has no network host. It can also surface after refactors that widen which URLs set `auth_target`.","solutions":["Ensure the packaged app's start URL is a full web URL with a host (`https://example.com`), not `about:blank`, `data:`, or a bare scheme","Guard the extraction: only install the auth delegate when `target_url.host_str()` is `Some`, otherwise skip delegate installation instead of panicking","If custom-protocol URLs must be supported, derive the allow-list key from `target_url.scheme()` or the full URL string rather than `host_str()`","Validate the URL early (at config/CLI parse time) so a hostless URL never reaches `build_window` as an auth target"],"exampleFix":"// before\nlet allowed_host = target_url\n    .host_str()\n    .expect(\"web URLs must have a host\")\n    .to_owned();\n// after\nlet allowed_host = match target_url.host_str() {\n    Some(host) => host.to_owned(),\n    None => {\n        log::warn!(\"auth target {target_url} has no host; skipping auth delegate\");\n        return;\n    }\n};","handlingStrategy":"validation","validationCode":"fn is_web_url_with_host(s: &str) -> bool {\n    matches!(url::Url::parse(s), Ok(u) if matches!(u.scheme(), \"http\" | \"https\") && u.host_str().is_some())\n}\n// validate the target before entering the auth flow","typeGuard":"fn web_host(url: &url::Url) -> Option<&str> {\n    if matches!(url.scheme(), \"http\" | \"https\") {\n        url.host_str()\n    } else {\n        None\n    }\n}","tryCatchPattern":"let Some(host) = target_url.host_str() else {\n    log::warn!(\"no host on auth target {target_url}; skipping auth delegate\");\n    return;\n};","preventionTips":["Reject hostless schemes (`about:`, `data:`, `javascript:`, custom protocols) at config/CLI validation time, before window creation","Only route genuine http(s) URLs into the basic-auth / certificate-error delegate path","Add a unit test asserting `build_window`-style handling for `about:blank` and `data:` inputs returns early instead of panicking"],"tags":["rust","url-parsing","macos","panic","tauri","basic-auth"],"backgroundTag":"missing-url-host","analyzedSha":"777dd552ade5fd49c96cf4cbab73312eba1011db","analyzedAt":"2026-09-05T10:03:52.999Z","contentChangedAt":"2026-09-05T10:03:52.999Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}