elkowar/eww · error
no pixbuf from theme.load_icon despite no error
Error message
no pixbuf from theme.load_icon despite no error
What it means
This is an .expect() on the Option inside Ok(pb) from theme.load_icon_for_scale: the GTK docs say that when load_icon_for_scale returns Ok the pixbuf may still be None. GTK yields Ok(None) in edge cases (e.g. the icon resolved to nothing usable for the requested size/scale, such as an empty or malformed icon theme entry), so the crate treats it as an internal invariant violation and panics.
Solutions
- Treat Ok(None) as a lookup failure: fall back to the fallback_icon('image-missing') path instead of panicking
- Validate the icon name / theme_path from the SNI item and log it when the lookup yields None
- Update GTK (gtk3/glib) packages — some versions had Ok(None) quirks with FORCE_SIZE at unusual scale factors
- Map None to an IconError (e.g. IconError::NotAvailable) so callers can degrade gracefully
- Ensure a complete icon theme is installed so lookups resolve for all sizes/scales
Example fix
// before
Ok(pb) => Ok(pb.expect("no pixbuf from theme.load_icon despite no error")),
// after
Ok(Some(pb)) => Ok(pb),
Ok(None) => {
log::warn!("theme returned no pixbuf for \"{}\" at {}px", icon_name, size);
Err(IconError::NotAvailable)
} Defensive patterns
Strategy: fallback
Validate before calling
// Validate inputs before the lookup
if icon_name.trim().is_empty() { return Err(IconError::NotAvailable); }
if let Some(p) = theme_path {
if !std::path::Path::new(p).exists() { log::warn!("theme path missing: {}", p); }
} Type guard
fn pixbuf_from_ok(pb: Option<gtk::gdk_pixbuf::Pixbuf>) -> Option<gtk::gdk_pixbuf::Pixbuf> {
pb.filter(|p| p.width() > 0 && p.height() > 0)
} Try / catch
match theme.load_icon_for_scale(icon_name, size, scale, gtk::IconLookupFlags::FORCE_SIZE) {
Ok(Some(pb)) => Ok(pb),
Ok(None) | Err(_) => fallback_icon(size, scale)
.map(Ok)
.unwrap_or(Err(IconError::NotAvailable)),
} Prevention
- Never assume Ok implies Some: handle the Option from load_icon_for_scale explicitly
- Fall back to the 'image-missing' icon when any lookup yields None
- Sanitize icon names and theme paths from untrusted SNI items
- Install a complete icon theme (adwaita/breeze) so lookups resolve at all sizes and scales
- Unit-test lookups at common scale factors (1x, 2x) against the target theme
When it happens
Trigger: load_icon_from_sni -> icon_from_name calls theme.load_icon_for_scale(icon_name, size, scale, FORCE_SIZE) and GTK returns Ok(None) — observed with icon names that do not resolve cleanly in the (possibly custom, theme_path-prepended) theme at the requested size/scale.
Common situations: Tray items advertising icon names absent from the theme while the theme lookup still 'succeeds'; HiDPI scale factors where no scaled variant exists; custom theme paths (prepend_search_path) pointing at incomplete icon theme directories; broken cached pixbufs in some GTK versions.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Could not get default gtk theme
- Error opening log file
- Error, trying to add multiple children to a…
- could not get default display
- OneToNElementsMap got into inconsistent state
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/73da75ff2eed1167.
Report an issue: GitHub.
Appendix: source
Thrown at crates/notifier_host/src/icon.rs:115
/// Load an icon with a given name from either the default (if `theme_path` is `None`), or from the
/// theme at a path.
fn icon_from_name(
icon_name: &str,
theme_path: Option<&str>,
size: i32,
scale: i32,
) -> std::result::Result<gtk::gdk_pixbuf::Pixbuf, IconError> {
let theme = if let Some(path) = theme_path {
let theme = gtk::IconTheme::new();
theme.prepend_search_path(path);
theme
} else {
gtk::IconTheme::default().expect("Could not get default gtk theme")
};
match theme.load_icon_for_scale(icon_name, size, scale, gtk::IconLookupFlags::FORCE_SIZE) {
Ok(pb) => Ok(pb.expect("no pixbuf from theme.load_icon despite no error")),
Err(e) => Err(IconError::LoadIconFromTheme {
icon_name: icon_name.to_owned(),
theme_path: theme_path.map(str::to_owned),
source: e,
}),
}
}
pub async fn load_icon_from_sni(
sni: &proxy::StatusNotifierItemProxy<'_>,
size: i32,
scale: i32,
) -> Option<gtk::gdk_pixbuf::Pixbuf> {
// "Visualizations are encouraged to prefer icon names over icon pixmaps if both are
// available."
let scaled_size = size * scale;
View on GitHub (pinned to 48f5aa8b37)