{"record":{"id":"bc8efc9b99cf7c35","repo":"flxzt/rnote","slug":"query-piet-font-family-returned-none-for-font-fami","errorCode":null,"errorMessage":"query piet font family returned None for font family '{font_family}","messagePattern":"query piet font family returned None for font family '(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/strokes/textstroke.rs","lineNumber":139,"sourceCode":"            piet::TextAttribute::TextColor(color) => Self::TextColor(Color::from(color)),\n            piet::TextAttribute::Style(font_style) => Self::Style(font_style.into()),\n            piet::TextAttribute::Underline(underline) => Self::Underline(underline),\n            piet::TextAttribute::Strikethrough(strikethrough) => Self::Strikethrough(strikethrough),\n        }\n    }\n}\n\nimpl TextAttribute {\n    pub fn try_into_piet<T>(self, piet_text: &mut T) -> anyhow::Result<piet::TextAttribute>\n    where\n        T: piet::Text,\n    {\n        match self {\n            TextAttribute::FontFamily(font_family) => piet_text\n                .font_family(font_family.as_str())\n                .map(piet::TextAttribute::FontFamily)\n                .ok_or_else(|| {\n                    anyhow::anyhow!(\n                        \"query piet font family returned None for font family '{font_family}\"\n                    )\n                }),\n            TextAttribute::FontSize(font_size) => Ok(piet::TextAttribute::FontSize(font_size)),\n            TextAttribute::FontWeight(font_weight) => Ok(piet::TextAttribute::Weight(\n                piet::FontWeight::new(font_weight),\n            )),\n            TextAttribute::TextColor(color) => {\n                Ok(piet::TextAttribute::TextColor(piet::Color::from(color)))\n            }\n            TextAttribute::Style(style) => {\n                Ok(piet::TextAttribute::Style(piet::FontStyle::from(style)))\n            }\n            TextAttribute::Underline(underline) => Ok(piet::TextAttribute::Underline(underline)),\n            TextAttribute::Strikethrough(strikethrough) => {\n                Ok(piet::TextAttribute::Strikethrough(strikethrough))\n            }\n        }","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/strokes/textstroke.rs#L121-L157","documentation":"When converting TextAttributes to piet attributes, a FontFamily attribute must be resolvable by the piet text backend (font_family()). If the backend has no font registered under that family name, it returns None and this error is thrown. It means the requested font family is not installed or not known to the font config system.","triggerScenarios":"Rendering a text stroke whose TextAttribute::FontFamily names a font not present on the system — e.g. after importing a document using a platform-specific or custom font, or a typo in the family name.","commonSituations":"Opening a .rnote file created on another machine with different fonts; headless Linux systems with minimal fontconfig; family names that differ between platforms (e.g. 'Helvetica' vs 'Arial').","solutions":["Install the missing font family on the system (or bundle it with the app)","Fall back to a default font family when piet's font_family() returns None instead of failing","Validate font availability (font-kit / fontconfig query) when loading text content and substitute missing families","Check for exact-name mismatches — query fontconfig with `fc-list` and use the canonical family string"],"exampleFix":"// before\npiet_text.font_family(font_family.as_str())\n    .map(piet::TextAttribute::FontFamily)\n    .ok_or_else(|| anyhow!(\"query piet font family returned None...\"))?\n// after\nlet family = piet_text.font_family(font_family.as_str())\n    .unwrap_or(piet_text.font_family(DEFAULT_FAMILY)?);\nOk(piet::TextAttribute::FontFamily(family))","handlingStrategy":"fallback","validationCode":"let available: Vec<String> = fontdb_query_families(); // or fc-list output\nlet family = if available.iter().any(|f| f == requested_family) { requested_family } else { DEFAULT_FAMILY.to_string() };","typeGuard":"fn font_available(piet_text: &impl piet::Text, family: &str) -> bool {\n    piet_text.font_family(family).is_some()\n}","tryCatchPattern":"match stroke.try_into_piet_attrs(piet_text) {\n    Ok(attrs) => attrs,\n    Err(e) if e.to_string().contains(\"font family returned None\") => {\n        log::warn!(\"font missing, using default: {e}\");\n        attrs_with_default_family()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always fall back to a known-installed default family instead of propagating the error","Substitute missing fonts at document load time and persist the substitution","Bundle common fonts with the app for consistent cross-platform rendering","Check `fc-list` coverage on headless/CI environments before text rendering tests"],"tags":["font","piet","text-rendering","missing-font"],"backgroundTag":"resource-not-found","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}