{"record":{"id":"9e3fc4974638063d","repo":"louis-e/arnis","slug":"failed-to-get-main-window","errorCode":null,"errorMessage":"Failed to get main window","messagePattern":"Failed to get main window","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/gui.rs","lineNumber":174,"sourceCode":"            gui_set_save_path,\n            gui_pick_save_directory,\n            gui_start_generation,\n            gui_get_version,\n            gui_get_update_info,\n            gui_get_platform,\n            gui_clear_tile_caches,\n            gui_get_world_map_data,\n            gui_show_in_folder,\n            gui_get_3d_model_attributions,\n            gui_get_terrain_preview,\n            gui_get_preview_landcover,\n            gui_get_preview_buildings,\n            gui_log\n        ])\n        .setup(|app| {\n            let app_handle = app.handle();\n            let main_window = tauri::Manager::get_webview_window(app_handle, \"main\")\n                .expect(\"Failed to get main window\");\n            progress::set_main_window(main_window);\n            Ok(())\n        })\n        .run(tauri::generate_context!())\n        .expect(\"Error while starting the application UI (Tauri)\");\n}\n\n/// Detects the default Minecraft Java Edition saves directory for the current OS.\n/// Checks standard install paths including Flatpak on Linux.\n/// Falls back to Desktop, then current directory.\nfn detect_minecraft_saves_directory() -> PathBuf {\n    // Try standard Minecraft saves directories per OS\n    let mc_saves: Option<PathBuf> = if cfg!(target_os = \"windows\") {\n        env::var(\"APPDATA\")\n            .ok()\n            .map(|appdata| PathBuf::from(appdata).join(\".minecraft\").join(\"saves\"))\n    } else if cfg!(target_os = \"macos\") {\n        dirs::home_dir().map(|home| {","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/louis-e/arnis/blob/34048924d9365795fb0d832e76140a3fbdc413d9/src/gui.rs#L156-L192","documentation":"During Tauri app setup, run_gui looks up the window labeled \"main\" via tauri::Manager::get_webview_window and .expect()s it to exist, storing it for progress notifications. The expect panics with this message when no window labeled \"main\" was created at that point, aborting startup since the progress reporting path cannot work without it.","triggerScenarios":"The tauri.conf.json (or generate_context! config) defines no window with label \"main\" (renamed, different label, or windows array empty); the window is created dynamically after setup instead of statically; multiple windows where the main one has a different label; a config refactor or migration dropped the windows section.","commonSituations":"Renaming the window label in tauri.conf.json (e.g. to the app title) while src/gui.rs still looks up \"main\"; switching from a static config window to programmatically-created windows placed outside setup; copying run_gui into a new app whose config lacks the window; Tauri v1-to-v2 migration changing Manager::get_webview_window usage/labels.","solutions":["Ensure tauri.conf.json declares a window with label \"main\" (\"label\": \"main\", \"visible\": true) matching the get_webview_window(app_handle, \"main\") call.","If windows are created programmatically, create the main window inside .setup() before the lookup, or move the lookup after creation.","Replace .expect with graceful error handling (match/ok_or + early return or eprintln) so a missing window reports a clear message instead of panicking.","Verify the label string is exact — labels are case-sensitive and must match config and lookup.","After a Tauri version upgrade, check the migration guide for window API/config changes and re-run the app with the updated config."],"exampleFix":"// before (src/gui.rs, setup)\nlet main_window = tauri::Manager::get_webview_window(app_handle, \"main\")\n    .expect(\"Failed to get main window\");\n// after\nlet main_window = tauri::Manager::get_webview_window(app_handle, \"main\")\n    .unwrap_or_else(|| {\n        eprintln!(\"window 'main' not found; check tauri.conf.json labels\");\n        tauri::WebviewWindowBuilder::new(app_handle, \"main\", tauri::WebviewUrl::App(\"index.html\".into()))\n            .build()\n            .expect(\"Failed to create main window\")\n    });","handlingStrategy":"validation","validationCode":"// at startup, before relying on the window\nif let Some(w) = tauri::Manager::get_webview_window(app_handle, \"main\") {\n    progress::set_main_window(w);\n} else {\n    eprintln!(\"warning: no window labeled 'main'; progress UI disabled\");\n}","typeGuard":"fn main_window_exists(handle: &tauri::AppHandle) -> bool {\n    tauri::Manager::get_webview_window(handle, \"main\").is_some()\n}","tryCatchPattern":"// Rust has no try-catch for panics; avoid expect and handle the Option:\nmatch tauri::Manager::get_webview_window(app_handle, \"main\") {\n    Some(w) => progress::set_main_window(w),\n    None => eprintln!(\"Failed to get main window; check tauri.conf.json\"),\n}","preventionTips":["Keep the window label \"main\" in tauri.conf.json in sync with get_webview_window calls.","Prefer match/unwrap_or over expect for windows that config may rename.","After Tauri upgrades, diff the window config schema and labels.","Add a startup smoke test that asserts the main window exists."],"tags":["tauri","rust","window-management","startup","panic"],"backgroundTag":"window-not-found","analyzedSha":"34048924d9365795fb0d832e76140a3fbdc413d9","analyzedAt":"2026-09-03T14:05:17.283Z","contentChangedAt":"2026-09-03T14:05:17.283Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}