{"record":{"id":"bc70cb201edf84eb","repo":"RightNow-AI/openfang","slug":"invalid-server-url","errorCode":null,"errorMessage":"Invalid server URL","messagePattern":"Invalid server URL","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openfang-desktop/src/lib.rs","lineNumber":115,"sourceCode":"            commands::get_agent_count,\n            commands::import_agent_toml,\n            commands::import_skill_file,\n            commands::get_autostart,\n            commands::set_autostart,\n            commands::check_for_updates,\n            commands::install_update,\n            commands::open_config_dir,\n            commands::open_logs_dir,\n        ])\n        .setup(move |app| {\n            // Create the main window pointing directly at the embedded HTTP server.\n            // We do NOT define windows in tauri.conf.json because Tauri would try to\n            // load index.html from embedded assets (which don't exist), causing a race\n            // condition where AssetNotFound overwrites the navigated page.\n            let _window = WebviewWindowBuilder::new(\n                app,\n                \"main\",\n                WebviewUrl::External(url.parse().expect(\"Invalid server URL\")),\n            )\n            .title(\"OpenFang\")\n            .inner_size(1280.0, 800.0)\n            .min_inner_size(800.0, 600.0)\n            .center()\n            .visible(true)\n            .build()?;\n\n            // Set up system tray (desktop only)\n            #[cfg(desktop)]\n            tray::setup_tray(app)?;\n\n            // Spawn background task to forward critical kernel events as native\n            // OS notifications. Only truly critical events — crashes, hard quota\n            // limits, and kernel shutdown. Health checks and quota warnings are\n            // too noisy for desktop notifications.\n            let app_handle = app.handle().clone();\n            let mut event_rx = kernel_for_notifications.event_bus.subscribe_all();","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/RightNow-AI/openfang/blob/acf2587e46be174c10200489c9a2d23a39a98aeb/crates/openfang-desktop/src/lib.rs#L97-L133","documentation":"`run()` builds the URL string `http://127.0.0.1:{port}` and parses it into a Tauri `WebviewUrl::External(...)` which requires a `url::Url`. The `.expect(\"Invalid server URL\")` panics if `str::parse::<Url>()` fails. With a well-formed literal and a valid port this should never fail in practice — it fires only if `port` produced a malformed URL (e.g. NaN/overflow through formatting) or the literal string is edited incorrectly.","triggerScenarios":"`port` value formatting into the URL is out of range or non-numeric, the base literal `http://127.0.0.1:{port}` is modified to an invalid scheme/host, or the port is left as 0/unset by a failed/short-circuited server startup path.","commonSituations":"After refactoring how the port is obtained (e.g. making `server_handle.port` optional or defaulting to 0), editing the URL format string with a typo, or constructing the URL from user/config-supplied host strings.","solutions":["Check how `port` is produced (crates/openfang-desktop/src/lib.rs:45) — ensure `start_server` returned a real bound port, not 0 or a default.","Validate the formatted URL parses before handing it to Tauri and log the offending string.","Use `Url::parse` with error propagation instead of `.expect` so a bad port yields a readable error."],"exampleFix":"// before\nWebviewUrl::External(url.parse().expect(\"Invalid server URL\")),\n\n// after\nlet parsed = url::Url::parse(&url)\n    .map_err(|e| anyhow!(\"Invalid server URL '{url}': {e}\"))?;\nWebviewUrl::External(parsed),","handlingStrategy":"validation","validationCode":"let url_str = format!(\"http://127.0.0.1:{port}\");\nlet parsed: url::Url = url::Url::parse(&url_str)\n    .map_err(|e| anyhow!(\"bad server url '{url_str}': {e}\"))?;\nif parsed.port() != Some(port) {\n    return Err(anyhow!(\"port mismatch in url {url_str}\"));\n}","typeGuard":"fn is_valid_http_url(s: &str) -> bool {\n    url::Url::parse(s).map(|u| u.scheme() == \"http\" || u.scheme() == \"https\").unwrap_or(false)\n}","tryCatchPattern":"// parse with error propagation, no expect\nlet external = url.parse().map_err(|e| anyhow!(\"Invalid server URL '{url}': {e}\"))?;","preventionTips":["Never let port default to 0/unset before formatting the URL","Always parse-and-check URLs before passing to WebviewUrl::External","Log the exact URL string on failure for diagnosis","Keep the URL literal centralized so refactors can't corrupt it"],"tags":["url","tauri","parsing","desktop"],"backgroundTag":"invalid-url-parse","analyzedSha":"acf2587e46be174c10200489c9a2d23a39a98aeb","analyzedAt":"2026-09-02T22:42:28.464Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}