flxzt/rnote · error

failed to parse `size` attribute in XoppText with node id

Error message

failed to parse `size` attribute in XoppText with node id {:?}, could not find attribute

What it means

Thrown by XoppText::load_from_xml when a `<text>` element has no `size` attribute. The value is parsed as f64 into XoppText.size, and since font size is mandatory in the XOPP text schema, its absence raises this anyhow error with the node id.

Solutions

  1. Add size to the <text> element, e.g. size="12.0".
  2. Regenerate the file ensuring all required text attributes (font, size, x, y, color) are present.
  3. Re-save via Xournal++ to normalize the XML, then retry import.

Example fix

// before (file XML)
<text font="Sans" x="10" y="20">Hello</text>
// after (file XML)
<text font="Sans" size="12" x="10" y="20">Hello</text>
Defensive patterns

Strategy: validation

Validate before calling

fn text_sizes_parse(xml: &str) -> Result<(), String> {
    for (i, chunk) in xml.split("<text").skip(1).enumerate() {
        let head = chunk.split('>').next().unwrap_or("");
        match head.split("size=\"").nth(1).and_then(|r| r.split('\"').next()) {
            Some(v) if v.parse::<f64>().is_err() => return Err(format!("text #{i} size not a number: {v}")),
            None => return Err(format!("text #{i} missing `size` attribute")),
            _ => {}
        }
    }
    Ok(())
}

Type guard

fn has_numeric_attr(attrs: &[(&str, &str)], name: &str) -> bool {
    attrs.iter().any(|(k, v)| *k == name && v.parse::<f64>().is_ok())
}

Try / catch

match import_xopp(path) {
    Err(e) if e.to_string().contains("`size` attribute in XoppText") => {
        eprintln!("Text element missing/invalid size; fix XML or re-save in Xournal++: {e:#}");
    }
    Err(e) => eprintln!("import failed: {e:#}"),
    Ok(doc) => { /* proceed */ }
}

Prevention

When it happens

Trigger: Importing a .xopp file whose <text> element is missing the `size` attribute (external generation, hand edits, corruption). Note the error also fires if parse::<f64>() of the value fails, but the primary documented case is the missing attribute.

Common situations: Scripts writing text elements without size; manual XML edits; files produced by older/incompatible exporters.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/4ba39b37e8e665c3. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/fileformats/xoppformat.rs:877

    pub text: String,
}

impl XmlLoadable for XoppText {
    fn load_from_xml(&mut self, node: Node) -> anyhow::Result<()> {
        self.font = node
            .attribute("font")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse `font` attribute in XoppText with node id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .to_string();

        self.size = node
            .attribute("size")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse `size` attribute in XoppText with node id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .parse::<f64>()?;

        self.x = node
            .attribute("x")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse `x` attribute in XoppText with node id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .parse::<f64>()?;

        self.y = node
            .attribute("y")

View on GitHub (pinned to bbc5354502)