{"record":{"id":"c22dad8f27b2625e","repo":"tonhowtf/omniget","slug":"not-found","errorCode":null,"errorMessage":"{} not found","messagePattern":"(.+?) not found","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/commands/browser_extension.rs","lineNumber":36,"sourceCode":"fn read_bundled_manifest_version(app: &AppHandle, browser: &str) -> Option<String> {\n    let resource = format!(\"browser-extension/{}/manifest.json\", browser);\n    let path = app\n        .path()\n        .resolve(resource, tauri::path::BaseDirectory::Resource)\n        .ok()?;\n    let raw = std::fs::read_to_string(&path).ok()?;\n    let v: serde_json::Value = serde_json::from_str(&raw).ok()?;\n    v.get(\"version\")?.as_str().map(|s| s.to_string())\n}\n\nfn extension_export_dir(app: &AppHandle, browser: &str) -> Option<PathBuf> {\n    let base = app.path().app_data_dir().ok()?;\n    Some(base.join(\"browser-extension\").join(browser))\n}\n\nfn copy_recursive(src: &Path, dst: &Path) -> std::io::Result<()> {\n    if !src.exists() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::NotFound,\n            format!(\"{} not found\", src.display()),\n        ));\n    }\n    if src.is_file() {\n        if let Some(parent) = dst.parent() {\n            std::fs::create_dir_all(parent)?;\n        }\n        std::fs::copy(src, dst)?;\n        return Ok(());\n    }\n    std::fs::create_dir_all(dst)?;\n    for entry in std::fs::read_dir(src)? {\n        let entry = entry?;\n        let from = entry.path();\n        let to = dst.join(entry.file_name());\n        copy_recursive(&from, &to)?;\n    }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/commands/browser_extension.rs#L18-L54","documentation":"copy_recursive in the browser_extension export command requires the source path to exist before copying. When src does not exist it returns an io::Error with ErrorKind::NotFound and the message \"<path> not found\". This is a guard so browser_extension_export fails with a clear per-path message instead of copying nothing silently.","triggerScenarios":"browser_extension_export calls copy_recursive with a source directory (browser profile's extension folder, e.g. the browser_extension_dir for a given browser) that is missing on disk; or recursion encounters a child entry deleted between readdir and copy.","commonSituations":"User selects a browser they never launched (no profile/extension dir exists); unsupported or renamed browser profile layout; extension removed by the browser; wrong browser name key passed to the export command.","solutions":["Check the source path exists before invoking the export and return a user-facing message listing valid browsers.","Verify the browser name/profile mapping produces the correct directory for the installed browser version.","Launch the source browser at least once so the profile and extension directory are created.","Make copy_recursive skip missing source with a warning instead of failing the whole export when multiple sources are involved."],"exampleFix":"// before\nfn copy_recursive(src: &Path, dst: &Path) -> std::io::Result<()> {\n    if !src.exists() {\n        return Err(std::io::Error::new(std::io::ErrorKind::NotFound, format!(\"{} not found\", src.display())));\n    }\n    ...\n}\n\n// after\nfn copy_recursive(src: &Path, dst: &Path) -> std::io::Result<()> {\n    if !src.exists() {\n        tracing::warn!(\"source missing, skipping: {}\", src.display());\n        return Ok(()); // or map to a typed ExportError::SourceMissing(src.to_path_buf())\n    }\n    ...\n}","handlingStrategy":"validation","validationCode":"if (!src.existsSync(srcPath)) throw new Error(`extension source missing: ${srcPath}; is this browser installed?`);\nawait invoke('browser_extension_export', { browser });","typeGuard":null,"tryCatchPattern":"try {\n  await invoke('browser_extension_export', { browser });\n} catch (msg) {\n  if (typeof msg === 'string' && msg.endsWith('not found')) {\n    showSetupHint(`No extension directory for \"${browser}\" — launch it once first.`);\n  }\n}","preventionTips":["List only browsers whose profile directories exist before showing export options","Check src.exists() (or fs.existsSync) before invoking the command","Handle deleted-mid-copy race by tolerating NotFound on children"],"tags":["filesystem","rust","tauri","browser-extension"],"backgroundTag":"file-not-found","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}