{"record":{"id":"28384e887de0cf32","repo":"niri-wm/niri","slug":"no-default-icon","errorCode":null,"errorMessage":"no default icon","messagePattern":"no default icon","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"src/cursor.rs","lineNumber":164,"sourceCode":"\n    /// Currently used cursor_image as a cursor provider.\n    pub fn cursor_image(&self) -> &CursorImageStatus {\n        &self.current_cursor\n    }\n\n    /// Set new cursor image provider.\n    pub fn set_cursor_image(&mut self, cursor: CursorImageStatus) {\n        self.current_cursor = cursor;\n    }\n\n    /// Load the cursor with the given `name` from the file system picking the closest\n    /// one to the given `size`.\n    fn load_xcursor(theme: &CursorTheme, name: &str, size: i32) -> anyhow::Result<XCursor> {\n        let _span = tracy_client::span!(\"load_xcursor\");\n\n        let path = theme\n            .load_icon(name)\n            .ok_or_else(|| anyhow!(\"no default icon\"))?;\n\n        let mut file = File::open(path).context(\"error opening cursor icon file\")?;\n        let mut buf = vec![];\n        file.read_to_end(&mut buf)\n            .context(\"error reading cursor icon file\")?;\n\n        let mut images = parse_xcursor(&buf).context(\"error parsing cursor icon file\")?;\n\n        let (width, height) = images\n            .iter()\n            .min_by_key(|image| (size - image.size as i32).abs())\n            .map(|image| (image.width, image.height))\n            .unwrap();\n\n        images.retain(move |image| image.width == width && image.height == height);\n\n        let animation_duration = images.iter().fold(0, |acc, image| acc + image.delay);\n","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/niri-wm/niri/blob/606284464d4a99bb35710fee68192bc71085ee7c/src/cursor.rs#L146-L182","documentation":"load_xcursor resolves a cursor name through the xcursor theme lookup (theme.load_icon(name)), which searches the configured theme and its inherited chain in ~/.icons, ~/.local/share/icons and /usr/share/icons. 'no default icon' means the lookup returned None: no cursor theme on disk provides an icon for that name. niri treats this softly: for most icons it logs 'error loading xcursor ...' and falls back to the default, and for CursorIcon::Default it falls back to a built-in cursor, so the visible symptom is a wrong/legacy pointer rather than a crash.","triggerScenarios":"Calling Manager::load_xcursor with a theme whose directory exists but lacks the requested icon file (e.g. a theme with only a few cursors installed), or when the configured cursor theme is not installed at all and no default theme (Adwaita/default) exists on a minimal system; also when XCURSOR_PATH/XCURSOR_THEME point somewhere unusual.","commonSituations":"Setting cursor-theme in niri config (or XCURSOR_THEME) to a theme that is not installed or has a different name than its directory; minimal distros/containers with no cursor theme package; partial theme installs where 'default'/'left_ptr' aliases are missing; typos in the theme name.","solutions":["Install a complete cursor theme: e.g. 'pacman -S bibata-cursor-theme' / 'apt install breeze-cursor-theme' / 'dnf install google-crosextra-carlito...' style package for your distro, plus adwaita-icon-theme as a fallback.","Point niri at a theme that actually exists: check 'ls ~/.icons ~/.local/share/icons /usr/share/icons' and set the config to the exact directory name: cursor { xcursor-theme \"Bibata-Modern-Classic\"; xcursor-size 24 }.","Verify the theme provides the default cursor: 'find /usr/share/icons/<theme> -name \"left_ptr*\" -o -name \"default*\"' should return files.","Clear stale caches/paths: unset weird XCURSOR_PATH and confirm XCURSOR_THEME matches the installed theme name."],"exampleFix":"// before: theme not installed, every lookup logs \"no default icon\"\ncursor {\n    xcursor-theme \"MyMissingTheme\"\n    xcursor-size 24\n}\n\n// after: theme that exists in /usr/share/icons\ncursor {\n    xcursor-theme \"Adwaita\"\n    xcursor-size 24\n}","handlingStrategy":"fallback","validationCode":"// Rust: confirm the theme exists and exposes a default cursor before using it\nlet theme = CursorTheme::new(&name, &search_paths);\nlet ok = theme\n    .load_icon(\"left_ptr\")\n    .or_else(|| theme.load_icon(\"default\"))\n    .is_some();\nanyhow::ensure!(ok, \"cursor theme '{name}' provides no default cursor; is it installed?\");","typeGuard":null,"tryCatchPattern":"match Self::load_xcursor(&theme, icon.name(), size) {\n    Ok(x) => Some(Rc::new(x)),\n    Err(_) => {\n        // niri's own pattern: unknown icons degrade to the default, default falls back to built-in\n        warn!(\"error loading xcursor {}, using fallback\", icon.name());\n        None // caller substitutes the default/built-in cursor\n    }\n}","preventionTips":["Always install a known-complete base theme (adwaita-icon-theme or breeze-cursor-theme) alongside any fancy theme.","Set xcursor-theme to the exact directory name under ~/.icons or /usr/share/icons.","Verify with: find /usr/share/icons/<theme> -name 'left_ptr*' — it must return files.","After switching themes, restart the app/compositor so lookups are redone against the new theme."],"tags":["cursor","xcursor","icon-theme","config","theming"],"backgroundTag":"cursor-theme-missing","analyzedSha":"606284464d4a99bb35710fee68192bc71085ee7c","analyzedAt":"2026-08-16T21:48:00.228Z","schemaVersion":2},"datasetVersion":"2026-08-18T00:17:09.346Z"}