{"record":{"id":"ea3729b3c1872892","repo":"flxzt/rnote","slug":"failed-to-parse-font-attribute-in-xopptext-with","errorCode":null,"errorMessage":"failed to parse `font` attribute in XoppText with node id {:?}, could not find attribute","messagePattern":"failed to parse `font` attribute in XoppText with node id (.+?), could not find attribute","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/fileformats/xoppformat.rs","lineNumber":867,"sourceCode":"    pub font: String,\n    /// The text size.\n    pub size: f64,\n    /// The x position of the upper left corner.\n    pub x: f64,\n    /// The y position of the upper left corner.\n    pub y: f64,\n    /// The text color.\n    pub color: XoppColor,\n    /// The text string.\n    pub text: String,\n}\n\nimpl XmlLoadable for XoppText {\n    fn load_from_xml(&mut self, node: Node) -> anyhow::Result<()> {\n        self.font = node\n            .attribute(\"font\")\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"failed to parse `font` attribute in XoppText with node id {:?}, could not find attribute\",\n                    node.id()\n                )\n            })?\n            .to_string();\n\n        self.size = node\n            .attribute(\"size\")\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"failed to parse `size` attribute in XoppText with node id {:?}, could not find attribute\",\n                    node.id()\n                )\n            })?\n            .parse::<f64>()?;\n\n        self.x = node\n            .attribute(\"x\")","sourceCodeStart":849,"sourceCodeEnd":885,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/fileformats/xoppformat.rs#L849-L885","documentation":"Thrown by XoppText::load_from_xml when a `<text>` element in the .xopp file has no `font` attribute. rnote reads the font name string into XoppText.font and requires it to reconstruct text styling, so a missing attribute aborts parsing with this error including the node id.","triggerScenarios":"Importing a .xopp file whose `<text>` element lacks `font` — e.g. files written by external scripts, hand-edited XML, or a producer assuming a default font and omitting the attribute.","commonSituations":"Programmatic xopp text generation omitting font; manual XML cleanup that removed the attribute; corrupted files.","solutions":["Add a font attribute to the <text> element, e.g. font=\"Sans\".","Regenerate the file ensuring every <text> element includes font and size.","Open and re-save the file in Xournal++ so required text attributes are written, then import."],"exampleFix":"// before (file XML)\n<text size=\"12\" x=\"10\" y=\"20\">Hello</text>\n// after (file XML)\n<text font=\"Sans\" size=\"12\" x=\"10\" y=\"20\">Hello</text>","handlingStrategy":"validation","validationCode":"fn text_elements_have_required_attrs(xml: &str) -> Result<(), String> {\n    const REQ: [&str; 5] = [\"font=\", \"size=\", \"x=\", \"y=\", \"color=\"];\n    for (i, chunk) in xml.split(\"<text\").skip(1).enumerate() {\n        let head = chunk.split('>').next().unwrap_or(\"\");\n        for r in REQ {\n            if !head.contains(r) {\n                return Err(format!(\"text #{i} missing attribute {}\", r.trim_end_matches('=')));\n            }\n        }\n    }\n    Ok(())\n}","typeGuard":"fn text_attrs_ok(attrs: &[(&str, &str)]) -> bool {\n    [\"font\", \"size\", \"x\", \"y\", \"color\"]\n        .iter()\n        .all(|req| attrs.iter().any(|(k, _)| k == req))\n}","tryCatchPattern":"match import_xopp(path) {\n    Err(e) if e.to_string().contains(\"attribute in XoppText\") => {\n        eprintln!(\"A <text> element is missing a required attribute (font/size/x/y/color): {e:#}\");\n    }\n    Err(e) => eprintln!(\"import failed: {e:#}\"),\n    Ok(doc) => { /* proceed */ }\n}","preventionTips":["Generate text elements with font, size, x, y, and color always present","Test generators on a minimal file round-tripped through Xournal++","Don't rely on defaults for attributes the XOPP format marks mandatory"],"tags":["parsing","xml","missing-attribute","xopp"],"backgroundTag":"missing-required-argument","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"}