flxzt/rnote · error

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

Error message

failed to parse `color` 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 `color` attribute. The value is passed to XoppColor::from_strokecolor_attr_value, and ok_or_else raises this error (with the node id) when the attribute is missing, since text color is required by the XOPP format.

Solutions

  1. Add a color attribute to the <text> element, e.g. color="black" or color="#000000ff".
  2. Regenerate the file ensuring all required <text> attributes (font, size, x, y, color) exist.
  3. Re-save the file via Xournal++ to restore canonical attributes, then import.

Example fix

// before (file XML)
<text font="Sans" size="12" x="100" y="50">Hello</text>
// after (file XML)
<text font="Sans" size="12" x="100" y="50" color="black">Hello</text>
Defensive patterns

Strategy: validation

Validate before calling

fn text_has_color(xml: &str) -> Result<(), String> {
    for (i, chunk) in xml.split("<text").skip(1).enumerate() {
        let head = chunk.split('>').next().unwrap_or("");
        if !head.contains("color=") {
            return Err(format!("text #{i} missing `color` attribute"));
        }
    }
    Ok(())
}

Type guard

fn text_attrs_ok(attrs: &[(&str, &str)]) -> bool {
    attrs.iter().any(|(k, _)| *k == "color")
}

Try / catch

match import_xopp(path) {
    Err(e) if e.to_string().contains("`color` attribute in XoppText") => {
        eprintln!("Text element missing color; add e.g. color=\"black\" 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 lacks the `color` attribute — external generators, hand edits, or files from incompatible producers. Also reachable if the value cannot be interpreted as a stroke color.

Common situations: Scripts writing text XML without color; manual removal of the attribute; files edited by tools other than Xournal++.

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/00cf10cf9e670c30. Report an issue: GitHub.

Appendix: source

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

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

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

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

        if let Some(text) = node.text() {
            self.text = text.to_string();
        }

        Ok(())
    }
}

impl XmlWritable for XoppText {
    fn write_to_xml(&self, w: &mut xmlwriter::XmlWriter) {
        w.set_preserve_whitespaces(true);
        w.start_element("text");
        w.write_attribute("font", &self.font);

View on GitHub (pinned to bbc5354502)